Web development went from server rendered applications to single page applications rendered fully on the client, and then it all got complicated. Next.js have now cleared away the old perspective of client and servers and provided us with a high performance framework which is a big black box containing both client and server. But don't worry, I'll here provide a FAQ with common questions about Next.js and its Server Components.
At least we get to use JavaScript for the server code
In This Article
- How To Read URL Params in a Client Component?
- How To Read URL Params in a Page File?
- How To Read URL Params in a Next.js Layout File?
- How To Read URL Params in a Server Component?
- Why Doesn't searchParams Exist in Next.js Layout Files?
- How Can I Skip the Root Layout for Some Pages in Next.js?
- How To Set Metadata Tags in App Router?
- How To Set Metadata Dynamically for an App Router Page?
- Can I Set Metadata in a Layout File?
- Can I Use Contexts with App Router?
- How To Use React Context in Server Components?
- Is it Possible to Render a Client Component in a Server Component?
- Can I Pass Props from a Server Component to a Client Component?
- Can I Use Server Components in Client Components?
- Can I Pass Props from a Client Component to a Server Component?
- Can I Use Server Actions in Server Components?
- Can I Use Server Actions in Client Components?
- Are Server Actions Stable in Next.js?
How To Make a Hero Image in Next.js 13 and 14
Dennis Persson ・ Nov 12 '23
1. How To Read URL Params in a Client Component?
If you need to read the pathname or query params from the URL in a Client Component, you can use the usePathname or useSearchParams to do so.
'use client'
import { usePathname, useSearchParams } from 'next/navigation'
const ClientComponent({ children, href }) {
const pathname = usePathname()
const searchParams = useSearchParams()
const search = searchParams.get('search')
return (
<div>Next.js usePathname and useSearchParams example</div>
<div>{pathname}</div>
<div>{search}</div>
)
}
export default ClientComponent
If you need to navigate programatically in a Client Component, you can use useRouter. For normal navigation, please use the built in Link component Next.js has.
'use client'
import { useRouter } from 'next/navigation'
const ClientComponent({ children }) {
const router = useRouter()
const handleClick = () => {
router.push('someUrl')
}
return (
<div onClick={handleClick}>Click me</div>
)
}
export default ClientComponent
2. How To Read URL Params in a Page File?
Params are automatically passed as props to the page component. You can simply use the provided prop.
const PageComponent({ params, searchParams }) {
const { slug } = params
return <div>Next.js URL params in page.tsx file</div>
}
export default PageComponent
3. How To Read URL Params in a Next.js Layout File?
If you need to read URL params in a layout component file, you have two options. First option is to create a Client Component inside the layout and read the params in the Client Component instead.
This may sound like a bad option if you use Next.js with the expectations to mostly use Server Components, but it actually is completely natural. The rest of your layout file, can still be rendered as a Server Component, it's just the Client Component itself which will need to be rendered on the client.
For instance, if you would use URL params to filter articles on a blog with the help of chips components, then only the component containing the chips would need to be a Client Component, the rest of the header could remain a Server Component.
On the website above, the red rectangle can be a Server Component, while the blue rectangle which depends on URL params can be a Client Component
The other option, might be the lesser good alternative. This is to add a middleware to your application which reads the URL params and passes it on to your layout component. This will give you flexibility to access the URL params, on the cost of disabling static rendering and client-side caching of your Server Components.
The 20 Most Common Use Cases for JavaScript Arrays
Dennis Persson ・ Oct 22 '23
4. How To Read URL Params in a Server Component?
In a arbitrary Server Component, which is neither a layout component or page component, you can get the URL params by passing them down as props from other components.
Important to remember is that Server Components which aren't page file components aren't normally refreshed during navigation, the components as a whole are serialized and sent to the client and only updates in rare cases. For that reason, you must be careful when using information from the URL in Server Components. The URL params will get outdated upon navigation.
5. Why Doesn't searchParams Exist in Next.js Layout Files?
searchParams are only available in page files for a reason. Page files will always re-render when you navigate between two pages. Since the component re-renders when the URL changes, we can for sure know that the URL params passed to the component are up to date.
The purpose of layout components, is to avoid unnecessary renderings and to contain static parts of the UI which aren't updated when the user navigates between pages. A layout component does therefore only re-render when the user navigates to another part of the screen where that component isn't visible. In the code, that means to navigate between two pages which don't share a common layout file as ancestor in the file tree.
Effectively, this means that the URL will change more often than layout files renders, and if we were to read URL params in a layout component, the component wouldn't get to know when the URL params updated. Remember that the layout file is a Server Component, it is rendered to HTML when it is first fetched and then cached on client so it never has to re-render.
To learn more, read the section above about how to read URL params in a Next.js layout file.
6. How Can I Skip the Root Layout for Some Pages in Next.js?
A Next.js project can have many layout files, technically each page can have its own. The top level layout file which wraps your whole application is called Root Layout.
Layout files allow you to re-use a component as a wrapper component for several pages. Most commonly, each Next.js applications has a Root Layout file which includes the applications main menu, such as a header menu or hero image.
While doing that, you will soon run into a question; can you skip the Root Layout for specific pages? And the answer is, yes you can. Next.js has a feature called Route Groups which allows you to have multiple Root Layouts. This means that different parts of your application can have different layouts, which also makes it possible to skip having any components at all in the layout for certain pages.
One thing to note here is that navigation between route groups will trigger a full page load. That is a natural consequence of replacing the top level Server Component in the application. It basically means, you render a completely new part of your application which is independent from the rest of all pages.
Why Server Components - A Brief History of Web
Dennis Persson ・ Jul 9 '23
7. How To Set Metadata Tags in App Router?
Next.js makes it very easy for you to set metadata for your app and pages. The only thing you have to do is to export a metadata object from any layout or page file in your application to set the metadata for that layout/page and down.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js Metadata Example',
description: 'Example of metadata in Next.js',
}
export default function MyPage() { ... }
If you need dynamic data, see the question below.
8. How To Set Metadata Dynamically for an App Router Page?
For most SEO optimized applications, setting static metadata isn't enough, since data will be unique to almost every page and even be loaded at runtime from a server. To set metadata dynamically in a Next.js page, use the provided generateMetadata function.
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
const data = await fetch('someUrl').then((res) => res.json())
return {
title: 'Next.js Dynamic Metadata Example',
description: data.pageDescription,
}
}
export default function MyPage() { ... }
Good to know is that the fetch function in Next.js by default caches duplicated requests. This is a general behavior, it isn't specific to metadata. Even requests in Server Components are cached when fetch is used. Although, it can be opted out from and even disabled automatically when certain Next.js features are used.
9. Can I Set Metadata in a Layout File?
Yes, you can set metadata in a layout file, both static and dynamically. Please see the questions about setting metadata above.
10. Can I Use Contexts with App Router?
It is possible to use React Contexts with the App Router in Next.js. You can preferably place the contexts in the root layout to make it available to all Client Components. The context will not be available to use in Server Components, and it will not mess up the render behavior of Server Components.
You can read about how it works in this article.
Do Contexts in Next.js 13 Make the Whole App Render on the Client?
Dennis Persson ・ Jul 30 '23
11. How To Use React Context in Server Components?
In Next.js, you can only use React contexts in Client Components. Server Components will not be affected by contexts in Client Components and it cannot read the context. See "Do Contexts in Next.js 13 Make the Whole App Render on the Client?" for more information.
However, dependent on your need, you might be fine with not having a context in your Server Component. By default, Next.js caches data retrieved in requests sent with the fetch function, meaning that you don't have to worry about duplicated request. If multiple Server Components need to fetch the same data, you can rely on the cache as an alternative to a sharing data through a context.
12. Is it Possible to Render a Client Component in a Server Component?
It's completely normal to render Client Components in Server Components. All props which are passed to the Client Component must be serializable though. Data which isn't serializable must be handled from within the Client Component instead.
13. Can I Pass Props from a Server Component to a Client Component?
Yes it is possible to pass props from a Server Component to a Client Component. As mentioned in the previous question, the data must be serializable.
14. Can I Use Server Components in Client Components?
It is possible to user Server Components in a Client Component, but with limitations. You cannot import Server Components in Client Components as usual, they will not be Server Components when doing so. What you will have to do, is to pass the Server Component as a prop or child to the Client Component.
Note specifically, because this tricks many developers. Next.js claim that components are Server Components by default, and that you have to use the "use client" directive to make it a Client Component. That is not the whole truth, because when you import any component in a Client Component, the imported component will be a Client Component, not a Server Component.
As mentioned above, you have to pass the Server Component as a prop if it should be treated as a Server Component. Next.js don't complain if you import what you think are Server Components into Client Components, they are simply just treated as Client Components without any warnings. So if you think you are using a lot of Server Components, you may actually not have that many at all.
How To Use MVVM in React Using Hooks and TypeScript
Dennis Persson ・ Apr 16 '23
15. Can I Pass Props from a Client Component to a Server Component?
No, it isn't possible to pass props from a Client Component to a Server Component. Server Components are rendered into HTML on server already before Client Components are rendered.
16. Can I Use Server Actions in Server Components?
Yes of course, they are made for that. See this example in the docs.
17. Can I Use Server Actions in Client Components?
Yes, but with a caveat. You cannot use server actions directly in your Client Component. What you can do, is can write the server action in a separate file, and use it in a Client Component, like shown in the docs.
However, if you try to use server actions directly in a component like it is done in a Server Component, then you would get this error.
It is not allowed to define inline "use server" annotated Server Actions in Client Components. │ To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.
As you can read there, you have one more option. You can define the server action in a Server Component and pass it as a prop to the Client Component if you would want that.
18. Are Server Actions Stable in Next.js?
In Next.js 14 server actions are considered stable. One thing to note though, Next.js is built upon React features which are still marked as experimental.
Server actions were experimental back in Next.js 13, so if in version 13, you will be asked to add server actions as an experimental feature in next.config.js
to use server actions, please enable the feature flag in your next.js config.
This is what you would need to add to next.config.js. Although I rather recommend to upgrade to Next.js 14.
experimental: {
serverActions: true,
},
Top comments (11)
great post! 👏
I wonder in a point "Can I Pass Props from a Client Component to a Server Component?", could we say we can pass through URL?
I mean, we do something like this
Thanks :)
router.refresh() should work I suppose, since it do refresh Server Components.
Although, I wouldn't recommend it. I would probably rather turn the Server Component into a Client Component and read the URL with useRouter (or pass as prop if they are not needed to be persisted in the URL).
The reason? Because that way, it all is handled automatically. Manually having to refresh the page when URL is changed is error-prone, one day that will likely turn into a bug.
Plus, if you would need to fully refresh your Server Component to get the URL params to it, you are probably better of with a Client Component, performance-wise.
Great article. I’ll love if permitted to add a little correction: client components are rendered in the server too, but hydrated in the client. This is a great article to understand: article
Yes, that's a great addition, for a full page reload. Not sure if I have written something which implies the opposite somewhere, but either way, it's a great point that should have been brought up as a question in this article.
Thanks for your comment. I did not understood what you meant by “for a full page reload”.
I added my comment based on your text here:
There’s a lot of confusion about the server-client rendering of next.js, that’s why I added the comment.
Lot of people think it’s bad to render client components as next.js was built for server rendering but that’s far away from the reality as you pointed out several times in your article.
Thanks for reading! Let me know if I should post more articles like this by writing a comment or reacting with some of the reactions ❤️🦄 🔥
Woah, loved the post. So much Next.js, haha!
You can also check out this, I'm not sure if it's helpful but it's related to Nextjs.
12 things you didn't know you could do with Nextjs
Anmol Baranwal ・ Feb 20
useRouter should be imported from next/navigation.
Thanks for pointing out. I updated it. My import was from old page components :)
Written well
Yup, that clears a lot of stuff 🎯. RSC are hard to understand initially considering they are a different mental model.