In the last lectures,
we again saw a client component in action
and we did already explore server and client components
earlier in this course in the essentials course section.
But it is important to understand
these different component types,
why they exist, how they work, and when to use which.
Because in NextJS applications we have
React Server Components which are components
that are only rendered on the server.
So where the entire component function
is only executed on the server, never on the client.
We have these kinds of components
and then we have client components which are also
initially pre-rendered on the server despite their name,
but which then also can be executed on the client side,
so in the browser, unlike Server components
and the error JS file,
the component defined in there must be
a client component for example.
And that's simply the case
because in a NextJS application,
errors cannot just be caused due to problems on the server,
but also potentially because some client side code fails
and therefore this error fallback component must be callable
on the client side.
That's why we have a client component here.
But all the other components we have in this application
thus far, all the other page components,
and also our own non-page components,
all these components are server components.
They're only rendered on the server, never on the client.
And you can see that if you console log something in there,
for example, news list.
If you do that, you'll notice
that if you open your browser developer tools
and they are the JavaScript console,
you won't see any log in there
no matter how much I navigate around.
So even though we're in that single page
application mode here, we don't see any news list log here.
On the other hand, if I opened a terminal
where the development server is running,
if I reload this news page for example,
I can see this news list log here,
which proves that it was executed on the server
because any logs we're seeing here in that terminal
where the development server are running
are server side logs logs, so produced by server side code.
Now by default in NextJS you should keep all your components
as server components.
You should not change them to client components
if you don't have to because there's just no reason
to unnecessarily potentially execute some code
on the client if it's not required to load there.
Rendering everything on the server is the better strategy.
But sometimes you need a client component, for example here
for the error page,
but also for another adjustment I wanna make here
that other adjustment I wanna make
is here in my main header.
There, I wanna add a second link
which leads us to the archive.
And for that alone, we don't need a client component.
We can just make it like this
and keep the main header as a server component.
And with that we now have that archive link.
But now I wanna highlight the currently active link,
so not just when we hover over it,
but instead when the related page is active.
And to do that I need to find out
what the currently active path is
and we can get that currently active path
by using the use path name hook,
which can be imported from next slash navigation.
This gives us a path value, which will be a string,
which is simply the currently active URL path.
We can then use that to find out which link
should be marked as active.
So we can do that by adding a class name here
and checking if the path which we got from use path name
is equal to slash news in this case,
or let's say whether it starts with slash news
so that nested pops also mark this link as active.
And if that's the case,
I wanna add a CSS class called active to this link.
Otherwise, I'll add undefined as a class,
so no class.
And then we can repeat that on the second link
and just check whether the path starts with slash archive.
So with that we have the logic
for potentially highlighting the links,
but we now would get an error if we save that.
We get an error because use path name only works
in client components and we also get the solution here
that we should add the use client directive
at the top of the file.
Well therefore here, we actually now have
to convert this component here to a client component
because otherwise it won't work.
Because this hook here like most needs a client component
around it in order to work.
So therefore here we should add this use client directive
at the top of the main header JS file
and with that added, if you save everything,
the error goes away and the active path is highlighted
and stays highlighted.
However, this solution has a small flaw
because whilst it works,
we now actually also converted a lot of markup
to client component markup,
even though it wouldn't need to be.
Because we really only need use client
because of use path name.
And we only need that
because of the link component where we wanna add
a CSS class conditionally.
And therefore in such scenarios
and in general when working with NextJS,
it is considered a good practice to outsource
that client site code
or that code that requires a client component
so that your client components are as small as possible
so that most of your component logic
and markup stays in the server component realm.
Hence here I'll add a new component,
the nav link JS file will hold it
where I'll export my component function nav link.
And this component now has the job of outputting
that potentially highlighted navigation link.
So I'll actually cut this link component logic here
from the main header JS file
and add it here as a returned JSX code in nav link.
And of course, we now also must copy this link component
import from the main header JS file
to the nav link JS file like this.
And also cut this use path name usage here
and move that into the nav link component
because that's the reason why we created a separate
component to begin with.
Because now we can and should also get rid
of that used path name import in main header
and get rid of the used client directive there.
And instead in the nav link component file,
we now add this use path name import
and the use client directive again.
But now it's a much smaller component with much less markup
that's marked as a client component.
Now of course this should now be configurable
and I expect to get a ref prop and the children prop,
let's say.
So that ref is actually set to whatever value is
received through that ref prop.
And the text between the link text is the content received
through the children prop.
And with that in the main header JS file,
we can and should now use this nav link component
and set ref to news here
and the text to news and down here.
Also use the nav link component and set ref to archive
and the text to archive.
And with that nav link is a client component,
but main header is a server component.
Now to finish nav link,
we also must tweak this logic here now
and actually replace this hard-coded starts with value,
with the ref value we received.
Like this.
And that's the offer.
A pretty common pattern you should be aware of
when building NextJS components.
If you must build a client component,
try to make it as small as possible
because with that, the application still works as before
but now we improved our code.