In the previous step
we introduced this NavBar component
that we are then using
in both our pages.
By writing a shared component
we can avoid duplicating the same code
over multiple pages.
However there still is
some duplication between our pages.
They all have the same basic structure,
with a "header" and a "main" section.
In fact, it is not unusual
for all the pages in a website
to share the same general layout.
It would be nice to be able to
define such layout in a single place,
like in a sort of template.
With Next.js we can do that
by creating a custom App component.
Inside "pages" we can create a new file
named "_app.js".
The name begins with an underscore
because it's a special file.
It's not a regular page.
But it's still a React component,
so we can write a function component as usual.
Now, this component will receive some props,
that are passed automatically
by the Next.js framework.
One such props is called "Component".
This is the page component
corresponding to the page being displayed.
So if we're rendering the index page for example,
"Component" will be our HomePage.
But if we load the "/about" path
it will be our AboutPage component.
The other prop we need is called "pageProps",
and as the name suggests
this contains props that
we need to pass to the page component.
As a minimum,
in our App we want to render
the "Component" representing the current page.
And we need to pass all the "pageProps"
to that component,
using the object spread syntax.
And then as usual, we need to export this as
the default export for this module.
So like this, our custom App component
simply renders the desired page,
without adding anything.
Now, let's add at least
a logging statement here,
so we can see when
this component is rendered.
Ok, let's save this file.
Now, when we first create
a custom App component,
we need to manually restart
the dev server.
This is one of the very few cases
where the dev server does not
automatically pick up the changes.
And that's because
the App component is special,
in that it's used for all the pages.
So let's stop the server,
with Ctrl+C,
and then launch "npm run dev" again".
Let's hide the terminal,
and reload the app.
You can see in the browser console
that our new App component was rendered first
and then the HomePage was also rendered.
So this proves that our App component
is getting called.
Now, what we wanted to do is
extract the common page layout
from our existing pages.
So let's copy all these elements,
and go and paste them into
the App component.
But here we want to keep only
the common elements.
The main section will be different
for each page
so let's remove this,
and in its place we want to render
this page-specific component.
So each page can basically insert
its own elements into this sort of template.
If we save now,
well, there's an error
because I forgot to import
the "NavBar" component.
But if we fix that
the App component will render
the common NavBar.
In fact we see two NavBars
on the page now,
that's because the HomePage
also displays its own header.
So we can remove it from here now,
given that it's already provided
by the common App component.
And this way we should see
a single NavBar.
We can actually remove this import as well.
Ok, the HomePage is working.
If we go to the About page,
again we'll see the NavBar twice.
Because the AboutPage still adds
its own header.
Let's remove it from here as well,
and also get rid of the import,
and that's it,
the About page looks good.
By the way, we could remove
the fragment that wraps the "main" element
in this code
but it will be useful later on
when we add some more stuff,
so I'm going to leave it there.
Also note in the browser console
how the App component is always rendered,
before every page.
In fact, now that we've seen this
I'm going to remove that log statement
otherwise it'll keep being logged
every single time.
Ok. But this is how
a custom App component works
in Next.js.
It's the perfect place to write
code that applies to all the pages
in your application.