We have a few different pages in our application,
but we didn't put any links yet, to
navigate from one page to another.
Before we get to that, we need to understand
a bit better how Next.js renders our pages.
So in this video I'll explain "prerendering",
focusing on the HomePage only.
Like all React function components,
this HomePage function will be called every
time the framework renders the component.
Let's add a log statement here,
printing a message to the console
any time this function is called.
In the terminal, we always have
our dev server running,
and it already printed a message there,
but let me clear the logs,
and see what happens when we load
the page in the browser.
You can see that the HomePage component
is rendered on the server.
And only on the server.
There is no message in the browser console.
This is different from a traditional
React Single Page Application,
where components are rendered in the browser.
Now, since we're running in dev mode,
the component will be re-rendered by the
server every time we request the page.
As we'll see later in this section,
it works a bit differently when
running in production mode.
Anyway, let's see in more detail what's going on,
by looking at the network traffic
in the Chrome Developer Tools.
This panel shows all the requests
sent by the browser.
When we load our home page,
the browser sends an HTTP request
to our web server,
that's running on localhost on port 3000.
For the home page, as we know the path is "/".
The server returns a response
that is an HTML document.
And the browser will then display that HTML.
If we look at the Response tab,
here we can see the full data
returned by the server.
It's all in one line, but we can click
this button to format it more nicely.
So this is the HTML returned
by the Next.js dev server,
and you can see that, inside the body,
it contains all the elements defined in our RootLayout,
like "header" and "footer".
And also the elements from our HomePage component,
that are the heading and the paragraph.
So, Next.js rendered all our React
components on the server
and returned the resulting HTML to the browser.
This is called "pre-rendering",
and it is in fact the main feature
provided by Next.js
compared to a traditional React
Single Page Application.
To show you this difference in action,
I have prepared a simple React project here,
with a page that's similar to
our Next.js application.
I set up the React project
using "Create React App",
that for many years was the recommended
way to initialize a React project.
Although that's no longer the case,
because even the official React documentation now
recommends using Next.js or similar framework.
Anyway, a traditional React project
has a single HTML file
that simply contains an empty "div" with an "id",
where React will dynamically
insert all our components.
This is done in the "index.jsx" file.
This code gets the element with that "id",
and then renders the "App" component inside it.
Where the "App" component is defined in this file,
and I made it similar to the RootLayout
in our Next.js project.
It has a "header" and a "footer",
then the HomePage component in the middle,
which is basically the same
as our Next.js HomePage,
except it says "React SPA" in the heading,
where "SPA" is short for Single Page Application.
Note that it also logs a console
message any time it's rendered.
Now, let's go and run this application.
This project uses the "react-scripts" command,
that's the one provided by Create React App.
If we type "npm start" this
will launch the dev server.
We already have the Next.js server
running on port 3000,
so the React server will need to
use a different port number.
It's running on port 3001,
and this is what the page looks like.
Now, let me show the browser console, so
we can see any messages logged there.
And let's repeat the same experiment,
by clearing the server logs,
and reloading the page.
You can see that, in this React application,
our HomePage component is rendered in the browser.
There are no log messages in the server.
Let's go and inspect the network requests as well.
Let me do a "hard reload",
to make sure it's not using the browser cache.
Again, the first request loads the HTML document.
But in this case you can see that
the body only contains an empty "div".
It doesn't have any of the elements
we see displayed on the page.
After loading this initial HTML from the server,
the browser will also load some JavaScript code,
from a script called "bundle.js",
and that code will insert the
elements we see on the page.
Let's do another little experiment.
In the DevTools settings, we
can "Disable JavaScript".
This will prevent the browser from loading
or running any JavaScript code.
Let's see what happens if we load the page now.
You can see that our React
app simply doesn't work.
We only see a message saying "You
need to enable JavaScript".
Without JavaScript, React cannot render
our components in the browser.
Let's see what happens in our Next.js app,
if we try the same experiment,
and disable JavaScript.
What do you think will happen in this case?
Let's try and reload the app.
You can see that our Next.js page
still displays correctly,
even without JavaScript.
That's because the Next.js server returns
a pre-rendered HTML document.
The browser simply needs to display
these elements on the page,
without the need to load and run
some separate JavaScript code.
Pre-rendering has a few advantages.
The main one is that our page will
be displayed more quickly,
precisely because the browser just needs
to display what's in the initial HTML.
Loading some separate JavaScript code, and
executing it to do client-side
rendering takes extra time.
So, a Next.js app will typically load faster
compared to a traditional React
Single Page Application.
It's also better for search engines like Google,
Bing, and so on.
In the past, search bots simply couldn't see
any dynamic content inserted by JavaScript.
These days at least the most important
search engines do support JavaScript,
but they still work better with pre-rendered HTML.
If you're interested in learning more about this,
I recommend watching the YouTube video on "How
Google Search indexes JavaScript sites".
You'll find the link in the
Resources for this lecture.
As we've seen, pre-rendering also means that
our website can work even without JavaScript.
Although if you want interactive
functionality in your pages
you'll still need JavaScript for that.
By the way, you may have noticed that
the page generated by Next.js still
includes some JavaScript files.
This is partly because we're using the dev server,
which injects some JavaScript code
to automatically reload the page
whenever we modify the code in our project.
But, as we'll see later in this section,
Next.js also uses JavaScript to
enable client-side navigation.
Anyway, let me re-enable JavaScript now,
otherwise we cannot really work on our project.
In the next video we'll talk about
React Server Components.