Dashboard
    </button>
  )
}
The useRouter provides methods such as push(), refresh(), and more. See the API reference for more information.
Recommendation: Use the <Link> component to navigate between routes unless you have a specific requirement for using useRouter.
How Navigation Works
A route transition is initiated using <Link> or calling router.push().
The router updates the URL in the browser's address bar.
The router avoids unnecessary work by re-using segments that haven't changed (e.g. shared layouts) from the client-side cache. This is also referred to as partial rendering.
If the conditions of soft navigation are met, the router fetches the new segment from the cache rather than the server. If not, the router performs a hard navigation and fetches the Server Component payload from the server.
If created, loading UI is shown from the server while the payload is being fetched.


If created, loading UI is shown from the server while the payload is being fetched.
The router uses the cached or fresh payload to render the new segments on the client.
Client-side Caching of Rendered Server Components
Good to know: This client-side cache is different from the server-side Next.js HTTP cache.
The new router has an in-memory client-side cache that stores the rendered result of Server Components (payload). The cache is split by route segments which allows invalidation at any level and ensures consistency across concurrent renders.
As users navigate around the app, the router will store the payload of previously fetched segments and prefetched segments in the cache.
This means, for certain cases, the router can re-use the cache instead of making a new request to the server. This improves performance by avoiding re-fetching data and re-rendering components unnecessarily.
Invalidating the Cache


Invalidating the Cache
Server Actions can be used to revalidate data on-demand by path (revalidatePath) or by cache tag (revalidateTag).
Prefetching
Prefetching is a way to preload a route in the background before it's visited. The rendered result of prefetched routes is added to the router's client-side cache. This makes navigating to a prefetched route near-instant.
By default, routes are prefetched as they become visible in the viewport when using the <Link> component. This can happen when the page first loads or through scrolling. Routes can also be programmatically prefetched using the prefetch method of the useRouter() hook.
Static and Dynamic Routes:
If the route is static, all the Server Component payloads for the route segments will be prefetched.


If the route is dynamic, the payload from the first shared layout down until the first loading.js file is prefetched. This reduces the cost of prefetching the whole route dynamically and allows instant loading states for dynamic routes.
Good to know:
Prefetching is only enabled in production.
Prefetching can be disabled by passing prefetch={false} to <Link>.
Soft Navigation
On navigation, the cache for changed segments is reused (if it exists), and no new requests are made to the server for data.
Conditions for Soft Navigation
On navigation, Next.js will use soft navigation if the route you are navigating to has been prefetched, and either doesn't include dynamic segments or has the same dynamic parameters as the current route.
For example, consider the following route that includes a dynamic [team] segment: /dashboard/[team]/*. The cached segments below /dashboard/[team]/* will only be invalidated when the [team] parameter changes.


Navigating from /dashboard/team-red/* to /dashboard/team-red/* will be a soft navigation.
Navigating from /dashboard/team-red/* to /dashboard/team-blue/* will be a hard navigation.
Hard Navigation
On navigation, the cache is invalidated and the server refetches data and re-renders the changed segments.
Back/Forward Navigation
Back and forward navigation (popstate event) has a soft navigation behavior. This means, the client-side cache is re-used and navigation is near-instant.
Focus and Scroll Management
By default, Next.js will set focus and scroll into view the segment that's changed on navigation.


Pages and Layouts
We recommend reading the Routing Fundamentals and Defining Routes pages before continuing.
The App Router inside Next.js 13 introduced new file conventions to easily create pages, shared layouts, and templates. This page will guide you through how to use these special files in your Next.js application.
Pages
A page is UI that is unique to a route. You can define pages by exporting a component from a page.js file. Use nested folders to define a route and a page.js file to make the route publicly accessible.
Create your first page by adding a page.js file inside the app directory:
app/page.tsx // `app/page.tsx` is the UI for the `/` URL
export default function Page() {
  return
Hello, Home page!

}
app/dashboard/page.tsx // `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {


export default function Page() {
  return
Hello, Dashboard Page!

}
Good to know:
A page is always the leaf of the route subtree.
.js, .jsx, or .tsx file extensions can be used for Pages.
A page.js file is required to make a route segment publicly accessible.
Pages are Server Components by default but can be set to a Client Component.
Pages can fetch data. View the Data Fetching section for more information.
Layouts
A layout is UI that is shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not re-render. Layouts can also be nested.
You can define a layout by default exporting a React component from a layout.js file. The component should accept a children prop that will be populated with a child layout (if it exists) or a child page during rendering.
app/dashboard/layout.tsx export default function DashboardLayout({


app/dashboard/layout.tsx export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (

      {/* Include shared UI here e.g. a header or sidebar */}

      {children}

  )
}
Good to know:
The top-most layout is called the Root Layout. This required layout is shared across all pages in an application. Root layouts must contain html and body tags.
Any route segment can optionally define its own Layout. These layouts will be shared across all pages in that segment.
Layouts in a route are nested by default. Each parent layout wraps child layouts below it using the React children prop.
You can use Route Groups to opt specific route segments in and out of shared layouts.


You can use Route Groups to opt specific route segments in and out of shared layouts.
Layouts are Server Components by default but can be set to a Client Component.
Layouts can fetch data. View the Data Fetching section for more information.
Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will automatically dedupe the requests without affecting performance.
Layouts do not have access to the current route segment(s). To access route segments, you can use useSelectedLayoutSegment or useSelectedLayoutSegments in a Client Component.
.js, .jsx, or .tsx file extensions can be used for Layouts.
A layout.js and page.js file can be defined in the same folder. The layout will wrap the page.
Root Layout (Required)


Root Layout (Required)
The root layout is defined at the top level of the app directory and applies to all routes. This layout enables you to modify the initial HTML returned from the server.
app/layout.tsx export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
Good to know:
The app directory must include a root layout.
The root layout must define <html> and <body> tags since Next.js does not automatically create them.
You can use the built-in SEO support to manage <head> HTML elements, for example, the <title> element.
You can use route groups to create multiple root layouts. See an example here.
The root layout is a Server Component by default and can not be set to a Client Component.


The root layout is a Server Component by default and can not be set to a Client Component.
Migrating from the pages directory: The root layout replaces the _app.js and _document.js files. View the migration guide.
Nesting Layouts
Layouts defined inside a folder (e.g. app/dashboard/layout.js) apply to specific route segments (e.g. acme.com/dashboard) and render when those segments are active. By default, layouts in the file hierarchy are nested, which means they wrap child layouts via their children prop.
app/dashboard/layout.tsx export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}
Good to know:
Only the root layout can contain <html> and <body> tags.


Only the root layout can contain <html> and <body> tags.
If you were to combine the two layouts above, the root layout (app/layout.js) would wrap the dashboard layout (app/dashboard/layout.js), which would wrap route segments inside app/dashboard/*.
The two layouts would be nested as such:
You can use Route Groups to opt specific route segments in and out of shared layouts.
Templates
Templates are similar to layouts in that they wrap each child layout or page. Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized.
There may be cases where you need those specific behaviors, and templates would be a more suitable option than layouts. For example:


Enter/exit animations using CSS or animation libraries.
Features that rely on useEffect (e.g logging page views) and useState (e.g a per-page feedback form).
To change the default framework behavior. For example, Suspense Boundaries inside layouts only show the fallback the first time the Layout is loaded and not when switching pages. For templates, the fallback is shown on each navigation.
Recommendation: We recommend using Layouts unless you have a specific reason to use Template.
A template can be defined by exporting a default React component from a template.js file. The component should accept a children prop which will be nested segments.
app/template.tsx export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}
The rendered output of a route segment with a layout and a template will be as such:
Output <Layout>
  {/* Note that the template is given a unique key. */}


Output <Layout>
  {/* Note that the template is given a unique key. */}
  <Template key={routeParam}>{children}</Template>
</Layout>
Modifying <head>
In the app directory, you can modify the <head> HTML elements such as title and meta using the built-in SEO support.
Metadata can be defined by exporting a metadata object or generateMetadata function in a layout.js or page.js file.
app/page.tsx import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Next.js',
}

export default function Page() {
  return '...'
}
Good to know: You should not manually add <head> tags such as <title> and <meta> to root layouts. Instead, you should use the Metadata API which automatically handles advanced requirements such as streaming and de-duplicating <head> elements.


Learn more about available metadata options in the API reference.


Middleware
Middleware allows you to run code before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.
Middleware runs before cached content and routes are matched. See Matching Paths for more details.
Convention
Use the file middleware.ts (or .js) in the root of your project to define Middleware. For example, at the same level as pages or app, or inside src if applicable.
Example
middleware.ts import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}

// See "Matching Paths" below to learn more
export const config = {


// See "Matching Paths" below to learn more
export const config = {
  matcher: '/about/:path*',
}
Matching Paths
Middleware will be invoked for every route in your project. The following is the execution order:
headers from next.config.js
redirects from next.config.js
Middleware (rewrites, redirects, etc.)
beforeFiles (rewrites) from next.config.js
Filesystem routes (public/, _next/static/, pages/, app/, etc.)
afterFiles (rewrites) from next.config.js
Dynamic Routes (/blog/[slug])
fallback (rewrites) from next.config.js
There are two ways to define which paths Middleware will run on:
Custom matcher config
Conditional statements
Matcher
matcher allows you to filter Middleware to run on specific paths.
middleware.js export const config = {
  matcher: '/about/:path*',
}


middleware.js export const config = {
  matcher: '/about/:path*',
}
You can match a single path or multiple paths with an array syntax:
middleware.js export const config = {
  matcher: ['/about/:path*', '/dashboard/:path*'],
}
The matcher config allows full regex so matching like negative lookaheads or character matching is supported. An example of a negative lookahead to match all except specific paths can be seen here:
middleware.js export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
}


],
}
Good to know: The matcher values need to be constants so they can be statically analyzed at build-time. Dynamic values such as variables will be ignored.
Configured matchers:
MUST start with /
Can include named parameters: /about/:path matches /about/a and /about/b but not /about/a/c
Can have modifiers on named parameters (starting with :): /about/:path* matches /about/a/b/c because * is zero or more. ? is zero or one and + one or more
Can use regular expression enclosed in parenthesis: /about/(.*) is the same as /about/:path*
Read more details on path-to-regexp documentation.
Good to know: For backward compatibility, Next.js always considers /public as /public/index. Therefore, a matcher of /public/:path will match.
Conditional Statements
middleware.ts import { NextResponse } from 'next/server'


Conditional Statements
middleware.ts import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/about')) {
    return NextResponse.rewrite(new URL('/about-2', request.url))
  }

  if (request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.rewrite(new URL('/dashboard/user', request.url))
  }
}
NextResponse
The NextResponse API allows you to:
redirect the incoming request to a different URL
rewrite the response by displaying a given URL
Set request headers for API Routes, getServerSideProps, and rewrite destinations
Set response cookies
Set response headers
To produce a response from Middleware, you can:
rewrite to a route (Page or Route Handler) that produces a response


rewrite to a route (Page or Route Handler) that produces a response
return a NextResponse directly. See Producing a Response
Using Cookies
Cookies are regular headers. On a Request, they are stored in the Cookie header. On a Response they are in the Set-Cookie header. Next.js provides a convenient way to access and manipulate these cookies through the cookies extension on NextRequest and NextResponse.
For incoming requests, cookies comes with the following methods: get, getAll, set, and delete cookies. You can check for the existence of a cookie with has or remove all cookies with clear.
For outgoing responses, cookies have the following methods get, getAll, set, and delete.
middleware.ts import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Assume a "Cookie:nextjs=fast" header to be present on the incoming request


// Getting cookies from the request using the `RequestCookies` API
  let cookie = request.cookies.get('nextjs')
  console.log(cookie) // => { name: 'nextjs', value: 'fast', Path: '/' }
  const allCookies = request.cookies.getAll()
  console.log(allCookies) // => [{ name: 'nextjs', value: 'fast' }]

  request.cookies.has('nextjs') // => true
  request.cookies.delete('nextjs')
  request.cookies.has('nextjs') // => false

  // Setting cookies on the response using the `ResponseCookies` API
  const response = NextResponse.next()
  response.cookies.set('vercel', 'fast')
  response.cookies.set({
    name: 'vercel',
    value: 'fast',
    path: '/',
  })
  cookie = response.cookies.get('vercel')


path: '/',
  })
  cookie = response.cookies.get('vercel')
  console.log(cookie) // => { name: 'vercel', value: 'fast', Path: '/' }
  // The outgoing response will have a `Set-Cookie:vercel=fast;path=/test` header.

  return response
}
Setting Headers
You can set request and response headers using the NextResponse API (setting request headers is available since Next.js v13.0.0).
middleware.ts import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Clone the request headers and set a new header `x-hello-from-middleware1`
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('x-hello-from-middleware1', 'hello')


requestHeaders.set('x-hello-from-middleware1', 'hello')

  // You can also set request headers in NextResponse.rewrite
  const response = NextResponse.next({
    request: {
      // New request headers
      headers: requestHeaders,
    },
  })

  // Set a new response header `x-hello-from-middleware2`
  response.headers.set('x-hello-from-middleware2', 'hello')
  return response
}
Good to know: Avoid setting large headers as it might cause 431 Request Header Fields Too Large error depending on your backend web server configuration.
Producing a Response
You can respond from Middleware directly by returning a Response or NextResponse instance. (This is available since Next.js v13.1.0)
middleware.ts import { NextRequest, NextResponse } from 'next/server'
import { isAuthenticated } from '@lib/auth'


import { isAuthenticated } from '@lib/auth'

// Limit the middleware to paths starting with `/api/`
export const config = {
  matcher: '/api/:function*',
}

export function middleware(request: NextRequest) {
  // Call our authentication function to check the request
  if (!isAuthenticated(request)) {
    // Respond with JSON indicating an error message
    return new NextResponse(
      JSON.stringify({ success: false, message: 'authentication failed' }),
      { status: 401, headers: { 'content-type': 'application/json' } }
    )
  }
}
Advanced Middleware Flags
In v13.1 of Next.js two additional flags were introduced for middleware, skipMiddlewareUrlNormalize and skipTrailingSlashRedirect to handle advanced use cases.


skipTrailingSlashRedirect allows disabling Next.js default redirects for adding or removing trailing slashes allowing custom handling inside middleware which can allow maintaining the trailing slash for some paths but not others allowing easier incremental migrations.
next.config.js module.exports = {
  skipTrailingSlashRedirect: true,
}
middleware.js const legacyPrefixes = ['/docs', '/blog']

export default async function middleware(req) {
  const { pathname } = req.nextUrl

  if (legacyPrefixes.some((prefix) => pathname.startsWith(prefix))) {
    return NextResponse.next()
  }

  // apply trailing slash handling
  if (
    !pathname.endsWith('/') &&
    !pathname.match(/((?!\.well-known(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+)/)
  ) {
    req.nextUrl.pathname += '/'
    return NextResponse.redirect(req.nextUrl)
  }


return NextResponse.redirect(req.nextUrl)
  }
}
skipMiddlewareUrlNormalize allows disabling the URL normalizing Next.js does to make handling direct visits and client-transitions the same. There are some advanced cases where you need full control using the original URL which this unlocks.
next.config.js module.exports = {
  skipMiddlewareUrlNormalize: true,
}
middleware.js export default async function middleware(req) {
  const { pathname } = req.nextUrl

  // GET /_next/data/build-id/hello.json

  console.log(pathname)
  // with the flag this now /_next/data/build-id/hello.json
  // without the flag this would be normalized to /hello
}
Version History


// without the flag this would be normalized to /hello
}
Version History
VersionChangesv13.1.0Advanced Middleware flags addedv13.0.0Middleware can modify request headers, response headers, and send responsesv12.2.0Middleware is stable, please see the upgrade guidev12.0.9Enforce absolute URLs in Edge Runtime (PR)v12.0.0Middleware (Beta) added


Intercepting RoutesIntercepting routes allows you to load a route within the current layout while keeping the context for the current page. This routing paradigm can be useful when you want to "intercept" a certain route to show a different route.
For example, when clicking on a photo from within a feed, a modal overlaying the feed should show up with the photo. In this case, Next.js intercepts the /feed route and "masks" this URL to show /photo/123 instead.
However, when navigating to the photo directly by for example when clicking a shareable URL or by refreshing the page, the entire photo page should render instead of the modal. No route interception should occur.
Convention
Intercepting routes can be defined with the (..) convention, which is similar to relative path convention ../ but for segments.
You can use:
(.) to match segments on the same level
(..) to match segments one level above


(.) to match segments on the same level
(..) to match segments one level above
(..)(..) to match segments two levels above
(...) to match segments from the root app directory
For example, you can intercept the photo segment from within the feed segment by creating a (..)photo directory.
Note that the (..) convention is based on route segments, not the file-system.
Examples
Modals
Intercepting Routes can be used together with Parallel Routes to create modals.
Using this pattern to create modals overcomes some common challenges when working with modals, by allowing you to:
Make the modal content shareable through a URL
Preserve context when the page is refreshed, instead of closing the modal
Close the modal on backwards navigation rather than going to the previous route
Reopen the modal on forwards navigation


Reopen the modal on forwards navigation
In the above example, the path to the photo segment can use the (..) matcher since @modal is a slot and not a segment. This means that the photo route is only one segment level higher, despite being two file-system levels higher.
Other examples could include opening a login modal in a top navbar while also having a dedicated /login page, or opening a shopping cart in a side modal.
View an example of modals with Intercepted and Parallel Routes.


Dynamic RoutesWhen you don't know the exact segment names ahead of time and want to create routes from dynamic data, you can use Dynamic Segments that are filled in at request time or prerendered at build time.
Convention
A Dynamic Segment can be created by wrapping a folder's name in square brackets: [folderName]. For example, [id] or [slug].
Dynamic Segments are passed as the params prop to layout, page, route, and generateMetadata functions.
Example
For example, a blog could include the following route app/blog/[slug]/page.js where [slug] is the Dynamic Segment for blog posts.
app/blog/[slug]/page.tsx export default function Page({ params }: { params: { slug: string } }) {
  return
My Post: {params.slug}

}


return
My Post: {params.slug}

}
RouteExample URLparamsapp/blog/[slug]/page.js/blog/a{ slug: 'a' }app/blog/[slug]/page.js/blog/b{ slug: 'b' }app/blog/[slug]/page.js/blog/c{ slug: 'c' }
See the generateStaticParams() page to learn how to generate the params for the segment.
Good to know: Dynamic Segments are equivalent to Dynamic Routes in the pages directory.
Generating Static Params
The generateStaticParams function can be used in combination with dynamic route segments to statically generate routes at build time instead of on-demand at request time.
app/blog/[slug]/page.tsx export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())

  return posts.map((post) => ({
    slug: post.slug,


return posts.map((post) => ({
    slug: post.slug,
  }))
}
The primary benefit of the generateStaticParams function is its smart retrieval of data. If content is fetched within the generateStaticParams function using a fetch request, the requests are automatically deduplicated. This means a fetch request with the same arguments across multiple generateStaticParams, Layouts, and Pages will only be made once, which decreases build times.
Use the migration guide if you are migrating from the pages directory.
See generateStaticParams server function documentation for more information and advanced use cases.
Catch-all Segments
Dynamic Segments can be extended to catch-all subsequent segments by adding an ellipsis inside the brackets [...folderName].
For example, app/shop/[...slug]/page.js will match /shop/clothes, but also /shop/clothes/tops, /shop/clothes/tops/t-shirts, and so on.


RouteExample URLparamsapp/shop/[...slug]/page.js/shop/a{ slug: ['a'] }app/shop/[...slug]/page.js/shop/a/b{ slug: ['a', 'b'] }app/shop/[...slug]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }
Optional Catch-all Segments
Catch-all Segments can be made optional by including the parameter in double square brackets: [[...folderName]].
For example, app/shop/[[...slug]]/page.js will also match /shop, in addition to /shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts.
The difference between catch-all and optional catch-all segments is that with optional, the route without the parameter is also matched (/shop in the example above).


RouteExample URLparamsapp/shop/[[...slug]]/page.js/shop{}app/shop/[[...slug]]/page.js/shop/a{ slug: ['a'] }app/shop/[[...slug]]/page.js/shop/a/b{ slug: ['a', 'b'] }app/shop/[[...slug]]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }
TypeScript
When using TypeScript, you can add types for params depending on your configured route segment.
app/blog/[slug]/page.tsx export default function Page({ params }: { params: { slug: string } }) {
  return
My Page

}
Routeparams Type Definitionapp/blog/[slug]/page.js{ slug: string }app/shop/[...slug]/page.js{ slug: string[] }app/[categoryId]/[itemId]/page.js{ categoryId: string, itemId: string }


Good to know: This may be done automatically by the TypeScript plugin in the future.


Parallel RoutesParallel Routing allows you to simultaneously or conditionally render one or more pages in the same layout. For highly dynamic sections of an app, such as dashboards and feeds on social sites, Parallel Routing can be used to implement complex routing patterns.
For example, you can simultaneously render the team and analytics pages.
Parallel Routing allows you to define independent error and loading states for each route as they're being streamed in independently.
Parallel Routing also allows you to conditionally render a slot based on certain conditions, such as authentication state. This enables fully separated code on the same URL.
Convention
Parallel routes are created using named slots. Slots are defined with the @folder convention, and are passed to the same-level layout as props.
Slots are not route segments and do not affect the URL structure. The file path /@team/members would be accessible at /members.
For example, the following file structure defines two explicit slots: @analytics and @team.


For example, the following file structure defines two explicit slots: @analytics and @team.
The folder structure above means that the component in app/layout.js now accepts the @analytics and @team slots props, and can render them in parallel alongside the children prop:
app/layout.tsx export default function Layout(props: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}
Good to know: The children prop is an implicit slot that does not need to be mapped to a folder. This means app/page.js is equivalent to app/@children/page.js.
Unmatched Routes
By default, the content rendered within a slot will match the current URL.


Unmatched Routes
By default, the content rendered within a slot will match the current URL.
In the case of an unmatched slot, the content that Next.js renders differs based on the routing technique and folder structure.
default.js
You can define a default.js file to render as a fallback when Next.js cannot recover a slot's active state based on the current URL.
Consider the following folder structure. The @team slot has a settings directory, but @analytics does not.
If you were to navigate from the root / to /settings, the content that gets rendered is different based on the type of navigation and the availability of the default.js file.
With @analytics/default.jsWithout @analytics/default.jsSoft Navigation@team/settings/page.js and @analytics/page.js@team/settings/page.js and @analytics/page.jsHard Navigation@team/settings/page.js and @analytics/default.js404
Soft Navigation


Soft Navigation
On a soft navigation - Next.js will render the slot's previously active state, even if it doesn't match the current URL.
Hard Navigation
On a hard navigation - a navigation that requires a full page reload - Next.js will first try to render the unmatched slot's default.js file. If that's not available, a 404 gets rendered.
The 404 for unmatched routes helps ensure that you don't accidentally render a route that shouldn't be parallel rendered.
useSelectedLayoutSegment(s)
Both useSelectedLayoutSegment and useSelectedLayoutSegments accept a parallelRoutesKey, which allows you read the active route segment within that slot.
app/layout.tsx 'use client'

import { useSelectedLayoutSegment } from 'next/navigation'

export default async function Layout(props: {
  //...
  authModal: React.ReactNode
}) {
  const loginSegments = useSelectedLayoutSegment('authModal')


}) {
  const loginSegments = useSelectedLayoutSegment('authModal')
  // ...
}
When a user navigates to @authModal/login, or /login in the URL bar, loginSegments will be equal to the string "login".
Examples
Modals
Parallel Routing can be used to render modals.
The @authModal slot renders a <Modal> component that can be shown by navigating to a matching route, for example /login.
app/layout.tsx export default async function Layout(props: {
  // ...
  authModal: React.ReactNode
}) {
  return (
    <>
      {/* ... */}
      {props.authModal}
    </>
  )
}
app/@authModal/login/page.tsx import { Modal } from 'components/modal'

export default function Login() {
  return (
    <Modal>

Login


return (
    <Modal>

Login

      {/* ... */}
    </Modal>
  )
}
To ensure that the contents of the modal don't get rendered when it's not active, you can create a default.js file that returns null.
app/@authModal/default.tsx export default function Default() {
  return null
}
Dismissing a modal
If a modal was initiated through client navigation, e.g. by using <Link href="/login">, you can dismiss the modal by calling router.back() or by using a Link component.
app/@authModal/login/page.tsx 'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'

export default async function Login() {
  const router = useRouter()
  return (
    <Modal>


const router = useRouter()
  return (
    <Modal>
       router.back()}>Close modal

Login

      ...
    </Modal>
  )
}
More information on modals is covered in the Intercepting Routes section.
If you want to navigate elsewhere and dismiss a modal, you can also use a catch-all route.
app/@authModal/[...catchAll]/page.tsx export default function CatchAll() {
  return null
}
Catch-all routes take precedence over default.js.
Conditional Routes
Parallel Routes can be used to implement conditional routing. For example, you can render a @dashboard or @login route depending on the authentication state.
app/layout.tsx import { getUser } from '@/lib/auth'

export default function Layout({
  dashboard,
  login,
}: {
  dashboard: React.ReactNode


dashboard,
  login,
}: {
  dashboard: React.ReactNode
  login: React.ReactNode
}) {
  const isLoggedIn = getUser()
  return isLoggedIn ? dashboard : login
}


Project Organization and File ColocationApart from routing folder and file conventions, Next.js is unopinionated about how you organize and colocate your project files.
This page shares default behavior and features you can use to organize your project.
Safe colocation by default
Project organization features
Project organization strategies
Safe colocation by default
In the app directory, nested folder hierarchy defines route structure.
Each folder represents a route segment that is mapped to a corresponding segment in a URL path.
However, even though route structure is defined through folders, a route is not publicly accessible until a page.js or route.js file is added to a route segment.
And, even when a route is made publicly accessible, only the content returned by page.js or route.js is sent to the client.
This means that project files can be safely colocated inside route segments in the app directory without accidentally being routable.
Good to know:


Good to know:
This is different from the pages directory, where any file in pages is considered a route.
While you can colocate your project files in app you don't have to. If you prefer, you can keep them outside the app directory.
Project organization features
Next.js provides several features to help you organize your project.
Private Folders
Private folders can be created by prefixing a folder with an underscore: _folderName
This indicates the folder is a private implementation detail and should not be considered by the routing system, thereby opting the folder and all its subfolders out of routing.
Since files in the app directory can be safely colocated by default, private folders are not required for colocation. However, they can be useful for:
Separating UI logic from routing logic.
Consistently organizing internal files across a project and the Next.js ecosystem.
Sorting and grouping files in code editors.


Sorting and grouping files in code editors.
Avoiding potential naming conflicts with future Next.js file conventions.
Good to know
While not a framework convention, you might also consider marking files outside private folders as "private" using the same underscore pattern.
You can create URL segments that start with an underscore by prefixing the folder name with %5F (the URL-encoded form of an underscore): %5FfolderName.
If you don't use private folders, it would be helpful to know Next.js special file conventions to prevent unexpected naming conflicts.
Route Groups
Route groups can be created by wrapping a folder in parenthesis: (folderName)
This indicates the folder is for organizational purposes and should not be included in the route's URL path.
Route groups are useful for:
Organizing routes into groups e.g. by site section, intent, or team.
Enabling nested layouts in the same route segment level:


Enabling nested layouts in the same route segment level:
Creating multiple nested layouts in the same segment, including multiple root layouts
Adding a layout to a subset of routes in a common segment
src Directory
Next.js supports storing application code (including app) inside an optional src directory. This separates application code from project configuration files which mostly live in the root of a project.
Module Path Aliases
Next.js supports Module Path Aliases which make it easier to read and maintain imports across deeply nested project files.
app/dashboard/settings/analytics/page.js // before
import { Button } from '../../../components/button'

// after
import { Button } from '@/components/button'
Project organization strategies
There is no "right" or "wrong" way when it comes to organizing your own files and folders in a Next.js project.


The following section lists a very high-level overview of common strategies. The simplest takeaway is to choose a strategy that works for you and your team and be consistent across the project.
Good to know: In our examples below, we're using components and lib folders as generalized placeholders, their naming has no special framework significance and your projects might use other folders like ui, utils, hooks, styles, etc.
Store project files outside of app
This strategy stores all application code in shared folders in the root of your project and keeps the app directory purely for routing purposes.
Store project files in top-level folders inside of app
This strategy stores all application code in shared folders in the root of the app directory.
Split project files by feature or route
This strategy stores globally shared application code in the root app directory and splits more specific application code into the route segments that use them.


Route GroupsIn the app directory, nested folders are normally mapped to URL paths. However, you can mark a folder as a Route Group to prevent the folder from being included in the route's URL path.
This allows you to organize your route segments and project files into logical groups without affecting the URL path structure.
Route groups are useful for:
Organizing routes into groups e.g. by site section, intent, or team.
Enabling nested layouts in the same route segment level:
Creating multiple nested layouts in the same segment, including multiple root layouts
Adding a layout to a subset of routes in a common segment
Convention
A route group can be created by wrapping a folder's name in parenthesis: (folderName)
Examples
Organize routes without affecting the URL path
To organize routes without affecting the URL, create a group to keep related routes together. The folders in parenthesis will be omitted from the URL (e.g. (marketing) or (shop)).


Even though routes inside (marketing) and (shop) share the same URL hierarchy, you can create a different layout for each group by adding a layout.js file inside their folders.
Opting specific segments into a layout
To opt specific routes into a layout, create a new route group (e.g. (shop)) and move the routes that share the same layout into the group (e.g. account and cart). The routes outside of the group will not share the layout (e.g. checkout).
Creating multiple root layouts
To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route groups. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html> and <body> tags need to be added to each root layout.
In the example above, both (marketing) and (shop) have their own root layout.
Good to know:


Good to know:
The naming of route groups has no special significance other than for organization. They do not affect the URL path.
Routes that include a route group should not resolve to the same URL path as other routes. For example, since route groups don't affect URL structure, (marketing)/about/page.js and (shop)/about/page.js would both resolve to /about and cause an error.
If you use multiple root layouts without a top-level layout.js file, your home page.js file should be defined in one of the route groups, For example: app/(marketing)/page.js.
Navigating across multiple root layouts will cause a full page load (as opposed to a client-side navigation). For example, navigating from /cart that uses app/(shop)/layout.js to /blog that uses app/(marketing)/layout.js will cause a full page load. This only applies to multiple root layouts.


Static and Dynamic RenderingIn Next.js, a route can be statically or dynamically rendered.
In a static route, components are rendered on the server at build time. The result of the work is cached and reused on subsequent requests.
In a dynamic route, components are rendered on the server at request time.
Static Rendering (Default)
By default, Next.js statically renders routes to improve performance. This means all the rendering work is done ahead of time and can be served from a Content Delivery Network (CDN) geographically closer to the user.
Static Data Fetching (Default)
By default, Next.js will cache the result of fetch() requests that do not specifically opt out of caching behavior. This means that fetch requests that do not set a cache option will use the force-cache option.
If any fetch requests in the route use the revalidate option, the route will be re-rendered statically during revalidation.


To learn more about caching data fetching requests, see the Caching and Revalidating page.
Dynamic Rendering
During static rendering, if a dynamic function or a dynamic fetch() request (no caching) is discovered, Next.js will switch to dynamically rendering the whole route at request time. Any cached data requests can still be re-used during dynamic rendering.
This table summarizes how dynamic functions and caching affect the rendering behavior of a route:
Data FetchingDynamic FunctionsRenderingStatic (Cached)NoStaticStatic (Cached)YesDynamicNot CachedNoDynamicNot CachedYesDynamic
Note how dynamic functions always opt the route into dynamic rendering, regardless of whether the data fetching is cached or not. In other words, static rendering is dependent not only on the data fetching behavior, but also on the dynamic functions used in the route.


Good to know: In the future, Next.js will introduce hybrid server-side rendering where layouts and pages in a route can be independently statically or dynamically rendered, instead of the whole route.
Dynamic Functions
Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are:
Using cookies() or headers() in a Server Component will opt the whole route into dynamic rendering at request time.
Using useSearchParams() in Client Components will skip static rendering and instead render all Client Components up to the nearest parent Suspense boundary on the client.
We recommend wrapping the Client Component that uses useSearchParams() in a <Suspense/> boundary. This will allow any Client Components above it to be statically rendered. Example.
Using the searchParams Pages prop will opt the page into dynamic rendering at request time.
Dynamic Data Fetching


Dynamic Data Fetching
Dynamic data fetches are fetch() requests that specifically opt out of caching behavior by setting the cache option to 'no-store' or revalidate to 0.
The caching options for all fetch requests in a layout or page can also be set using the segment config object.
To learn more about Dynamic Data Fetching, see the Data Fetching page.


Edge and Node.js Runtimes
In the context of Next.js, "runtime" refers to the set of libraries, APIs, and general functionality available to your code during execution.
Next.js has two server runtimes where you can render parts of your application code:
Node.js Runtime
Edge Runtime
Each runtime has its own set of APIs. Please refer to the Node.js Docs and Edge Docs for the full list of available APIs. Both runtimes can also support streaming depending on your deployment infrastructure.
By default, the app directory uses the Node.js runtime. However, you can opt into different runtimes (e.g. Edge) on a per-route basis.
Runtime Differences
There are many considerations to make when choosing a runtime. This table shows the major differences at a glance. If you want a more in-depth analysis of the differences, check out the sections below.


NodeServerlessEdgeCold Boot/~250msInstantHTTP StreamingYesYesYesIOAllAllfetchScalability/HighHighestSecurityNormalHighHighLatencyNormalLowLowestnpm PackagesAllAllA smaller subset
Edge Runtime
In Next.js, the lightweight Edge Runtime is a subset of available Node.js APIs.
The Edge Runtime is ideal if you need to deliver dynamic, personalized content at low latency with small, simple functions. The Edge Runtime's speed comes from its minimal use of resources, but that can be limiting in many scenarios.
For example, code executed in the Edge Runtime on Vercel cannot exceed between 1 MB and 4 MB, this limit includes imported packages, fonts and files, and will vary depending on your deployment infrastructure.
Node.js Runtime
Using the Node.js runtime gives you access to all Node.js APIs, and all npm packages that rely on them. However, it's not as fast to start up as routes using the Edge runtime.


Deploying your Next.js application to a Node.js server will require managing, scaling, and configuring your infrastructure. Alternatively, you can consider deploying your Next.js application to a serverless platform like Vercel, which will handle this for you.
Serverless Node.js
Serverless is ideal if you need a scalable solution that can handle more complex computational loads than the Edge Runtime. With Serverless Functions on Vercel, for example, your overall code size is 50MB including imported packages, fonts, and files.
The downside compared to routes using the Edge is that it can take hundreds of milliseconds for Serverless Functions to boot up before they begin processing requests. Depending on the amount of traffic your site receives, this could be a frequent occurrence as the functions are not frequently "warm".
Examples
Segment Runtime Option


Examples
Segment Runtime Option
You can specify a runtime for individual route segments in your Next.js application. To do so, declare a variable called runtime and export it. The variable must be a string, and must have a value of either 'nodejs' or 'edge' runtime.The following example demonstrates a page route segment that exports a runtime with a value of 'edge':app/page.tsx export const runtime = 'edge' // 'nodejs' (default) | 'edge'You can also define runtime on a layout level, which will make all routes under the layout run on the edge runtime:app/layout.tsx export const runtime = 'edge' // 'nodejs' (default) | 'edge'If the segment runtime is not set, the default nodejs runtime will be used. You do not need to use the runtime option if you do not plan to change from the Node.js runtime.


Server ActionsServer Actions are an alpha feature in Next.js, built on top of React Actions. They enable server-side data mutations, reduced client-side JavaScript, and progressively enhanced forms. They can be defined inside Server Components and/or called from Client Components:
With Server Components:
app/add-to-cart.js import { cookies } from 'next/headers'

// Server action defined inside a Server Component
export default function AddToCart({ productId }) {
  async function addItem(data) {
    'use server'

    const cartId = cookies().get('cartId')?.value
    await saveToDb({ cartId, data })
  }

  return (
    <form action={addItem}>
      <button type="submit">Add to Cart</button>
    </form>
  )
}
With Client Components:
app/actions.js 'use server'

export async function addItem(data) {


app/actions.js 'use server'

export async function addItem(data) {
  const cartId = cookies().get('cartId')?.value
  await saveToDb({ cartId, data })
}
app/add-to-cart.js 'use client'

import { addItem } from './actions.js'

// Server Action being called inside a Client Component
export default function AddToCart({ productId }) {
  return (
    <form action={addItem}>
      <button type="submit">Add to Cart</button>
    </form>
  )
}
Good to know:
Using Server Actions will opt into running the React experimental channel.
React Actions, useOptimistic, and useFormStatus are not a Next.js or React Server Components specific features.


Next.js integrates React Actions into the Next.js router, bundler, and caching system, including adding data mutation APIs like revalidateTag and revalidatePath.
Convention
You can enable Server Actions in your Next.js project by enabling the experimental serverActions flag.
next.config.js module.exports = {
  experimental: {
    serverActions: true,
  },
}
Creation
Server Actions can be defined in two places:
Inside the component that uses it (Server Components only)
In a separate file (Client and Server Components), for reusability. You can define multiple Server Actions in a single file.
With Server Components
Create a Server Action by defining an asynchronous function with the "use server" directive at the top of the function body. This function should have serializable arguments and a serializable return value based on the React Server Components protocol.
app/server-component.js export default function ServerComponent() {
  async function myAction() {


app/server-component.js export default function ServerComponent() {
  async function myAction() {
    'use server'
    // ...
  }
}
With Client Components
If you're using a Server Action inside a Client Component, create your action in a separate file with the "use server" directive at the top of the file. Then, import the Server Action into your Client Component:
app/actions.js 'use server'

export async function myAction() {
  // ...
}
app/client-component.js 'use client'

import { myAction } from './actions'

export default function ClientComponent() {
  return (
    <form action={myAction}>
      <button type="submit">Add to Cart</button>
    </form>
  )
}


</form>
  )
}
Good to know: When using a top-level "use server" directive, all exports below will be considered Server Actions. You can have multiple Server Actions in a single file.
Invocation
You can invoke Server Actions using the following methods:
Using action: React's action prop allows invoking a Server Action on a <form> element.
Using formAction: React's formAction prop allows handling <button>, <input type="submit">, and <input type="image"> elements in a <form>.
Custom Invocation with startTransition: Invoke Server Actions without using action or formAction by using startTransition. This method disables Progressive Enhancement.
action
You can use React's action prop to invoke a Server Action on a form element. Server Actions passed with the action prop act as asynchronous side effects in response to user interaction.
app/add-to-cart.js import { cookies } from 'next/headers'


app/add-to-cart.js import { cookies } from 'next/headers'

export default function AddToCart({ productId }) {
  async function addItem(data) {
    'use server'

    const cartId = cookies().get('cartId')?.value
    await saveToDb({ cartId, data })
  }

  return (
    <form action={addItem}>
      <button type="submit">Add to Cart</button>
    </form>
  )
}
Good to know: An action is similar to the HTML primitive action
formAction
You can use formAction prop to handle Form Actions on elements such as button, input type="submit", and input type="image". The formAction prop takes precedence over the form's action.
app/form.js export default function Form() {
  async function handleSubmit() {
    'use server'
    // ...
  }


async function handleSubmit() {
    'use server'
    // ...
  }

  async function submitImage() {
    'use server'
    // ...
  }

  return (
    <form action={handleSubmit}>
      <input type="text" name="name" />
      <input type="image" formAction={submitImage} />
      <button type="submit">Submit</button>
    </form>
  )
}
Good to know: A formAction is the HTML primitive formaction. React now allows you to pass functions to this attribute.
Custom invocation using startTransition
You can also invoke Server Actions without using action or formAction. You can achieve this by using startTransition provided by the useTransition hook, which can be useful if you want to use Server Actions outside of forms, buttons, or inputs.


Good to know: Using startTransition disables the out-of-the-box Progressive Enhancement.
app/components/example-client-component.js 'use client'

import { useTransition } from 'react'
import { addItem } from '../actions'

function ExampleClientComponent({ id }) {
  let [isPending, startTransition] = useTransition()

  return (
    <button onClick={() => startTransition(() => addItem(id))}>
      Add To Cart
    </button>
  )
}
app/actions.js 'use server'

export async function addItem(id) {
  await addItemToDb(id)
  // Marks all product pages for revalidating
  revalidatePath('/product/[id]')
}
Custom invocation without startTransition
If you aren't doing Server Mutations, you can directly pass the function as a prop like any other function.


app/posts/[id]/page.tsx import kv from '@vercel/kv'
import LikeButton from './like-button'

export default function Page({ params }: { params: { id: string } }) {
  async function increment() {
    'use server'
    await kv.incr(`post:id:${params.id}`)
  }

  return <LikeButton increment={increment} />
}
app/post/[id]/like-button.tsx 'use client'

export default function LikeButton({
  increment,
}: {
  increment: () => Promise<void>
}) {
  return (
    <button
      onClick={async () => {
        await increment()
      }}
    >
      Like
    </button>
  )
}
Enhancements
Experimental useOptimistic


</button>
  )
}
Enhancements
Experimental useOptimistic
The experimental useOptimistic hook provides a way to implement optimistic updates in your application. Optimistic updates are a technique that enhances user experience by making the app appear more responsive.
When a Server Action is invoked, the UI is updated immediately to reflect the expected outcome, instead of waiting for the Server Action's response.
app/thread.js 'use client'

import { experimental_useOptimistic as useOptimistic, useRef } from 'react'
import { send } from './actions.js'

export function Thread({ messages }) {
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [...state, { message: newMessage, sending: true }]
  )
  const formRef = useRef()

  return (


)
  const formRef = useRef()

  return (

      {optimisticMessages.map((m) => (

          {m.message}
          {m.sending ? 'Sending...' : ''}

      ))}
      <form
        action={async (formData) => {
          const message = formData.get('message')
          formRef.current.reset()
          addOptimisticMessage(message)
          await send(message)
        }}
        ref={formRef}
      >
        <input type="text" name="message" />
      </form>

  )
}
Experimental useFormStatus
The experimental useFormStatus hook can be used within Form Actions, and provides the pending property.
app/form.js 'use client'


app/form.js 'use client'

import { experimental_useFormStatus as useFormStatus } from 'react-dom'

function Submit() {
  const { pending } = useFormStatus()

  return (
    <input
      type="submit"
      className={pending ? 'button-pending' : 'button-normal'}
      disabled={pending}
    >
      Submit
    </input>
  )
}
Progressive Enhancement
Progressive Enhancement allows a <form> to function properly without JavaScript, or with JavaScript disabled. This allows users to interact with the form and submit data even if the JavaScript for the form hasn't been loaded yet or if it fails to load.
Both Server Form Actions and Client Form Actions support Progressive Enhancement, using one of two strategies:
If a Server Action is passed directly to a <form>, the form is interactive even if JavaScript is disabled.


If a Client Action is passed to a <form>, the form is still interactive, but the action will be placed in a queue until the form has hydrated. The <form> is prioritized with Selective Hydration, so it happens quickly.
app/components/example-client-component.js 'use client'

import { useState } from 'react'
import { handleSubmit } from './actions.js'

export default function ExampleClientComponent({ myAction }) {
  const [input, setInput] = useState()

  return (
    <form action={handleSubmit} onChange={(e) => setInput(e.target.value)}>
      {/* ... */}
    </form>
  )
}
In both cases, the form is interactive before hydration occurs. Although Server Actions have the additional benefit of not relying on client JavaScript, you can still compose additional behavior with Client Actions where desired without sacrificing interactivity.
Size Limitation


Size Limitation
By default, the maximum size of the request body sent to a Server Action is 1MB. This prevents large amounts of data being sent to the server, which consumes a lot of server resource to parse.
However, you can configure this limit using the experimental serverActionsBodySizeLimit option. It can take the number of bytes or any string format supported by bytes, for example 1000, '500kb' or '3mb'.
next.config.js module.exports = {
  experimental: {
    serverActions: true,
    serverActionsBodySizeLimit: '2mb',
  },
}
Examples
Usage with Client Components
Import
Server Actions cannot be defined within Client Components, but they can be imported. To use Server Actions in Client Components, you can import the action from a file containing a top-level "use server" directive.
app/actions.js 'use server'

export async function addItem() {


app/actions.js 'use server'

export async function addItem() {
  // ...
}
app/components/example-client-component.js 'use client'

import { useTransition } from 'react'
import { addItem } from '../actions'

function ExampleClientComponent({ id }) {
  let [isPending, startTransition] = useTransition()

  return (
    <button onClick={() => startTransition(() => addItem(id))}>
      Add To Cart
    </button>
  )
}
Props
Although importing Server Actions is recommended, in some cases you might want to pass down a Server Action to a Client Component as a prop.
For example, you might want to use a dynamically generated value within the action. In that case, passing a Server Action down as a prop might be a viable solution.


app/components/example-server-component.js import { ExampleClientComponent } from './components/example-client-component.js'

function ExampleServerComponent({ id }) {
  async function updateItem(data) {
    'use server'
    modifyItem({ id, data })
  }

  return <ExampleClientComponent updateItem={updateItem} />
}
app/components/example-client-component.js 'use client'

function ExampleClientComponent({ updateItem }) {
  async function action(formData) {
    await updateItem(formData)
  }

  return (
    <form action={action}>
      <input type="text" name="name" />
      <button type="submit">Update Item</button>
    </form>
  )
}
On-demand Revalidation


</form>
  )
}
On-demand Revalidation
Server Actions can be used to revalidate data on-demand by path (revalidatePath) or by cache tag (revalidateTag).
 import { revalidateTag } from 'next/cache'

async function revalidate() {
  'use server'
  revalidateTag('blog-posts')
}
Validation
The data passed to a Server Action can be validated or sanitized before invoking the action. For example, you can create a wrapper function that receives the action as its argument, and returns a function that invokes the action if it's valid.
app/actions.js 'use server'

import { withValidate } from 'lib/form-validation'

export const action = withValidate((data) => {
  // ...
})
lib/form-validation.js export function withValidate(action) {
  return async (formData) => {
    'use server'


return async (formData) => {
    'use server'

    const isValidData = verifyData(formData)

    if (!isValidData) {
      throw new Error('Invalid input.')
    }

    const data = process(formData)
    return action(data)
  }
}
Using headers
You can read incoming request headers such as cookies and headers within a Server Action.
 import { cookies } from 'next/headers'

async function addItem(data) {
  'use server'

  const cartId = cookies().get('cartId')?.value

  await saveToDb({ cartId, data })
}
Additionally, you can modify cookies within a Server Action.
 import { cookies } from 'next/headers';

async function create(data) {
  'use server';

  const cart = await createCart():


'use server';

  const cart = await createCart():
  cookies().set('cartId', cart.id)
  // or
  cookies().set({
    name: 'cartId',
    value: cart.id,
    httpOnly: true,
    path: '/'
  })
}
Glossary
Actions
Actions are an experimental feature in React, allowing you to run async code in response to a user interaction.
Actions are not Next.js or React Server Components specific, however, they are not yet available in the stable version of React. When using Actions through Next.js, you are opting into using the React experimental channel.
Actions are defined through the action prop on an element. Typically when building HTML forms, you pass a URL to the action prop. With Actions, React now allows you to pass a function directly.


React also provides built-in solutions for optimistic updates with Actions. It's important to note new patterns are still being developed and new APIs may still be added.
Form Actions
Actions integrated into the web standard <form> API, and enable out-of-the-box progressive enhancement and loading states. Similar to the HTML primitive formaction.
Server Functions
Functions that run on the server, but can be called on the client.
Server Actions
Server Functions called as an action.
Server Actions can be progressively enhanced by passing them to a form element's action prop. The form is interactive before any client-side JavaScript has loaded. This means React hydration is not required for the form to submit.
Server Mutations
Server Actions that mutates your data and calls redirect, revalidatePath, or revalidateTag.


Data FetchingThe Next.js App Router allows you to fetch data directly in your React components by marking the function as async and using await for the Promise.
Data fetching is built on top of the fetch() Web API and React Server Components. When using fetch(), requests are automatically deduped by default.
Next.js extends the fetch options object to allow each request to set its own caching and revalidating.
async and await in Server Components
You can use async and await to fetch data in Server Components.
app/page.tsx async function getData() {
  const res = await fetch('https://api.example.com/...')
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.

  // Recommendation: handle errors
  if (!res.ok) {
    // This will activate the closest `error.js` Error Boundary
    throw new Error('Failed to fetch data')


throw new Error('Failed to fetch data')
  }

  return res.json()
}

export default async function Page() {
  const data = await getData()

  return <main></main>
}
Good to know:
To use an async Server Component with TypeScript, ensure you are using TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.
Server Component Functions
Next.js provides helpful server functions you may need when fetching data in Server Components:
cookies()
headers()
use in Client Components
use is a new React function that accepts a promise conceptually similar to await. use handles the promise returned by a function in a way that is compatible with components, hooks, and Suspense. Learn more about use in the React RFC.


Wrapping fetch in use is currently not recommended in Client Components and may trigger multiple re-renders. For now, if you need to fetch data in a Client Component, we recommend using a third-party library such as SWR or React Query.
Good to know: We'll be adding more examples once fetch and use work in Client Components.
Static Data Fetching
By default, fetch will automatically fetch and cache data indefinitely.
 fetch('https://...') // cache: 'force-cache' is the default
Revalidating Data
To revalidate cached data at a timed interval, you can use the next.revalidate option in fetch() to set the cache lifetime of a resource (in seconds).
 fetch('https://...', { next: { revalidate: 10 } })
See Revalidating Data for more information.
Good to know:


See Revalidating Data for more information.
Good to know:
Caching at the fetch level with revalidate or cache: 'force-cache' stores the data across requests in a shared cache. You should avoid using it for user-specific data (i.e. requests that derive data from cookies() or headers())
Dynamic Data Fetching
To fetch fresh data on every fetch request, use the cache: 'no-store' option.
 fetch('https://...', { cache: 'no-store' })
Data Fetching Patterns
Parallel Data Fetching
To minimize client-server waterfalls, we recommend this pattern to fetch data in parallel:
app/artist/[username]/page.tsx import Albums from './albums'

async function getArtist(username: string) {
  const res = await fetch(`https://api.example.com/artist/${username}`)
  return res.json()
}


return res.json()
}

async function getArtistAlbums(username: string) {
  const res = await fetch(`https://api.example.com/artist/${username}/albums`)
  return res.json()
}

export default async function Page({
  params: { username },
}: {
  params: { username: string }
}) {
  // Initiate both requests in parallel
  const artistData = getArtist(username)
  const albumsData = getArtistAlbums(username)

  // Wait for the promises to resolve
  const [artist, albums] = await Promise.all([artistData, albumsData])

  return (
    <>
      <h1>{artist.name}</h1>
      <Albums list={albums}></Albums>
    </>
  )
}


</>
  )
}
By starting the fetch prior to calling await in the Server Component, each request can eagerly start to fetch requests at the same time. This sets the components up so you can avoid waterfalls.
We can save time by initiating both requests in parallel, however, the user won't see the rendered result until both promises are resolved.
To improve the user experience, you can add a suspense boundary to break up the rendering work and show part of the result as soon as possible:
artist/[username]/page.tsx import { getArtist, getArtistAlbums, type Album } from './api'

export default async function Page({
  params: { username },
}: {
  params: { username: string }
}) {
  // Initiate both requests in parallel
  const artistData = getArtist(username)
  const albumData = getArtistAlbums(username)


const albumData = getArtistAlbums(username)

  // Wait for the artist's promise to resolve first
  const artist = await artistData

  return (
    <>

{artist.name}

      {/* Send the artist information first,
          and wrap albums in a suspense boundary */}
      <Suspense fallback={
Loading...
}>
        <Albums promise={albumData} />
      </Suspense>
    </>
  )
}

// Albums Component
async function Albums({ promise }: { promise: Promise<Album[]> }) {
  // Wait for the albums promise to resolve
  const albums = await promise

  return (

      {albums.map((album) => (

{album.name}

      ))}

  )


))}

  )
}
Take a look at the preloading pattern for more information on improving components structure.
Sequential Data Fetching
To fetch data sequentially, you can fetch directly inside the component that needs it, or you can await the result of fetch inside the component that needs it:
app/artist/page.tsx // ...

async function Playlists({ artistID }: { artistID: string }) {
  // Wait for the playlists
  const playlists = await getArtistPlaylists(artistID)

  return (

      {playlists.map((playlist) => (

{playlist.name}

      ))}

  )
}

export default async function Page({
  params: { username },
}: {
  params: { username: string }
}) {


}: {
  params: { username: string }
}) {
  // Wait for the artist
  const artist = await getArtist(username)

  return (
    <>

{artist.name}

      <Suspense fallback={
Loading...
}>
        <Playlists artistID={artist.id} />
      </Suspense>
    </>
  )
}
By fetching data inside the component, each fetch request and nested segment in the route cannot start fetching data and rendering until the previous request or segment has completed.
Blocking Rendering in a Route
By fetching data in a layout, rendering for all route segments beneath it can only start once the data has finished loading.


In the pages directory, pages using server-rendering would show the browser loading spinner until getServerSideProps had finished, then render the React component for that page. This can be described as "all or nothing" data fetching. Either you had the entire data for your page, or none.
In the app directory, you have additional options to explore:
First, you can use loading.js to show an instant loading state from the server while streaming in the result from your data fetching function.
Second, you can move data fetching lower in the component tree to only block rendering for the parts of the page that need it. For example, moving data fetching to a specific component rather than fetching it at the root layout.
Whenever possible, it's best to fetch data in the segment that uses it. This also allows you to show a loading state for only the part of the page that is loading, and not the entire page.
Data Fetching without fetch()


Data Fetching without fetch()
You might not always have the ability to use and configure fetch requests directly if you're using a third-party library such as an ORM or database client.
In cases where you cannot use fetch but still want to control the caching or revalidating behavior of a layout or page, you can rely on the default caching behavior of the segment or use the segment cache configuration.
Default Caching Behavior
Any data fetching libraries that do not use fetch directly will not affect caching of a route, and will be static or dynamic depending on the route segment.
If the segment is static (default), the output of the request will be cached and revalidated (if configured) alongside the rest of the segment. If the segment is dynamic, the output of the request will not be cached and will be re-fetched on every request when the segment is rendered.
Good to know: Dynamic functions like cookies() and headers() will make the route segment dynamic.


Good to know: Dynamic functions like cookies() and headers() will make the route segment dynamic.
Segment Cache Configuration
As a temporary solution, until the caching behavior of third-party queries can be configured, you can use segment configuration to customize the cache behavior of the entire segment.
app/page.tsx import prisma from './lib/prisma'

export const revalidate = 3600 // revalidate every hour

async function getPosts() {
  const posts = await prisma.post.findMany()
  return posts
}

export default async function Page() {
  const posts = await getPosts()
  // ...
}


Revalidating DataNext.js allows you to update specific static routes without needing to rebuild your entire site. Revalidation (also known as Incremental Static Regeneration) allows you to retain the benefits of static while scaling to millions of pages.
There are two types of revalidation in Next.js:
Background: Revalidates the data at a specific time interval.
On-demand: Revalidates the data based on an event such as an update.
Background Revalidation
To revalidate cached data at a specific interval, you can use the next.revalidate option in fetch() to set the cache lifetime of a resource (in seconds).
 fetch('https://...', { next: { revalidate: 60 } })
If you want to revalidate data that does not use fetch (i.e. using an external package or query builder), you can use the route segment config.


app/page.tsx export const revalidate = 60 // revalidate this page every 60 seconds
In addition to fetch, you can also revalidate data using cache.
How it works
When a request is made to the route that was statically rendered at build time, it will initially show the cached data.
Any requests to the route after the initial request and before 60 seconds are also cached and instantaneous.
After the 60-second window, the next request will still show the cached (stale) data.
Next.js will trigger a regeneration of the data in the background.
Once the route generates successfully, Next.js will invalidate the cache and show the updated route. If the background regeneration fails, the old data would still be unaltered.
When a request is made to a route segment that hasn’t been generated, Next.js will dynamically render the route on the first request. Future requests will serve the static route segments from the cache.


Good to know: Check if your upstream data provider has caching enabled by default. You might need to disable (e.g. useCdn: false), otherwise a revalidation won't be able to pull fresh data to update the ISR cache. Caching can occur at a CDN (for an endpoint being requested) when it returns the Cache-Control header. ISR on Vercel persists the cache globally and handles rollbacks.
On-demand Revalidation
If you set a revalidate time of 60, all visitors will see the same generated version of your site for one minute. The only way to invalidate the cache is if someone visits the page after the minute has passed.
The Next.js App Router supports revalidating content on-demand based on a route or cache tag. This allows you to manually purge the Next.js cache for specific fetches, making it easier to update your site when:
Content from your headless CMS is created or updated.


Content from your headless CMS is created or updated.
Ecommerce metadata changes (price, description, category, reviews, etc).
Using On-Demand Revalidation
Data can be revalidated on-demand by path (revalidatePath) or by cache tag (revalidateTag).
For example, the following fetch adds the cache tag collection:
app/page.tsx export default async function Page() {
  const res = await fetch('https://...', { next: { tags: ['collection'] } })
  const data = await res.json()
  // ...
}
This cached data can then be revalidated on-demand by calling revalidateTag in a Route Handler.
app/api/revalidate/route.ts import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'

export async function GET(request: NextRequest) {


export async function GET(request: NextRequest) {
  const tag = request.nextUrl.searchParams.get('tag')
  revalidateTag(tag)
  return NextResponse.json({ revalidated: true, now: Date.now() })
}
Error Handling and Revalidation
If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data.


Caching DataNext.js has built-in support for caching data, both on a per-request basis (recommended) or for an entire route segment.
Per-request Caching
fetch()
By default, all fetch() requests are cached and deduplicated automatically. This means that if you make the same request twice, the second request will reuse the result from the first request.
app/page.tsx async function getComments() {
  const res = await fetch('https://...') // The result is cached
  return res.json()
}

// This function is called twice, but the result is only fetched once
const comments = await getComments() // cache MISS

// The second call could be anywhere in your application
const comments = await getComments() // cache HIT
Requests are not cached if:


const comments = await getComments() // cache HIT
Requests are not cached if:
Dynamic methods (next/headers, export const POST, or similar) are used and the fetch is a POST request (or uses Authorization or cookie headers)
fetchCache is configured to skip cache by default
revalidate: 0 or cache: 'no-store' is configured on individual fetch
Requests made using fetch can specify a revalidate option to control the revalidation frequency of the request.
app/page.tsx export default async function Page() {
  // revalidate this data every 10 seconds at most
  const res = await fetch('https://...', { next: { revalidate: 10 } })
  const data = res.json()
  // ...
}
React cache()


const data = res.json()
  // ...
}
React cache()
React allows you to cache() and deduplicate requests, memoizing the result of the wrapped function call. The same function called with the same arguments will reuse a cached value instead of re-running the function.
utils/getUser.ts import { cache } from 'react'

export const getUser = cache(async (id: string) => {
  const user = await db.user.findUnique({ id })
  return user
})
app/user/[id]/layout.tsx import { getUser } from '@utils/getUser'

export default async function UserLayout({
  params: { id },
}: {
  params: { id: string }
}) {
  const user = await getUser(id)
  // ...
}
app/user/[id]/page.tsx import { getUser } from '@utils/getUser'


export default async function Page({
  params: { id },
}: {
  params: { id: string }
}) {
  const user = await getUser(id)
  // ...
}
Although the getUser() function is called twice in the example above, only one query will be made to the database. This is because getUser() is wrapped in cache(), so the second request can reuse the result from the first request.
Good to know:
fetch() caches requests automatically, so you don't need to wrap functions that use fetch() with cache(). See automatic request deduping for more information.
In this new model, we recommend fetching data directly in the component that needs it, even if you're requesting the same data in multiple components, rather than passing the data between components as props.
We recommend using the server-only package to make sure server data fetching functions are never used on the client.
POST requests and cache()


POST requests and cache()
POST requests are automatically deduplicated when using fetch – unless they are inside of POST Route Handler or come after reading headers()/cookies(). For example, if you are using GraphQL and POST requests in the above cases, you can use cache to deduplicate requests. The cache arguments must be flat and only include primitives. Deep objects won't match for deduplication.
utils/getUser.ts import { cache } from 'react'

export const getUser = cache(async (id: string) => {
  const res = await fetch('...', { method: 'POST', body: '...' })
  // ...
})
Preload pattern with cache()
As a pattern, we suggest optionally exposing a preload() export in utilities or components that do data fetching.
components/User.tsx import { getUser } from '@utils/getUser'

export const preload = (id: string) => {


export const preload = (id: string) => {
  // void evaluates the given expression and returns undefined
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
  void getUser(id)
}
export default async function User({ id }: { id: string }) {
  const result = await getUser(id)
  // ...
}
By calling preload, you can eagerly start fetching data you're likely going to need.
app/user/[id]/page.tsx import User, { preload } from '@components/User'

export default async function Page({
  params: { id },
}: {
  params: { id: string }
}) {
  preload(id) // starting loading the user data now
  const condition = await fetchCondition()
  return condition ? <User id={id} /> : null
}
Good to know:


}
Good to know:
The preload() function can have any name. It's a pattern, not an API.
This pattern is completely optional and something you can use to optimize on a case-by-case basis.
This pattern is a further optimization on top of parallel data fetching. Now you don't have to pass promises down as props and can instead rely on the preload pattern.
Combining cache, preload, and server-only
You can combine the cache function, the preload pattern, and the server-only package to create a data fetching utility that can be used throughout your app.
utils/getUser.ts import { cache } from 'react'
import 'server-only'

export const preload = (id: string) => {
  void getUser(id)
}

export const getUser = cache(async (id: string) => {
  // ...
})


export const getUser = cache(async (id: string) => {
  // ...
})
With this approach, you can eagerly fetch data, cache responses, and guarantee that this data fetching only happens on the server.
The getUser.ts exports can be used by layouts, pages, or components to give them control over when a user's data is fetched.
Segment-level Caching
Good to know: We recommend using per-request caching for improved granularity and control over caching.
Segment-level caching allows you to cache and revalidate data used in route segments.
This mechanism allows different segments of a path to control the cache lifetime of the entire route. Each page.tsx and layout.tsx in the route hierarchy can export a revalidate value that sets the revalidation time for the route.
app/page.tsx export const revalidate = 60 // revalidate this segment every 60 seconds
Good to know:


Good to know:
If a page, layout, and fetch request inside components all specify a revalidate frequency, the lowest value of the three will be used.
Advanced: You can set fetchCache to 'only-cache' or 'force-cache' to ensure that all fetch requests opt into caching but the revalidation frequency might still be lowered by individual fetch requests. See fetchCache for more information.


CSS Modules
Next.js has built-in support for CSS Modules using the .module.css extension.
CSS Modules locally scope CSS by automatically creating a unique class name. This allows you to use the same class name in different files without worrying about collisions. This behavior makes CSS Modules the ideal way to include component-level CSS.
Example
CSS Modules can be imported into any file inside the app directory:app/dashboard/layout.tsx import styles from './styles.module.css'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return
{children}

}app/dashboard/styles.module.css .dashboard {
  padding: 24px;
}
CSS Modules are an optional feature and are only enabled for files with the .module.css extension.
Regular <link> stylesheets and global CSS files are still supported.


Regular <link> stylesheets and global CSS files are still supported.
In production, all CSS Module files will be automatically concatenated into many minified and code-split .css files.
These .css files represent hot execution paths in your application, ensuring the minimal amount of CSS is loaded for your application to paint.
Global Styles
Global styles can be imported into any layout, page, or component inside the app directory.
Good to know: This is different from the pages directory, where you can only import global styles inside the _app.js file.
For example, consider a stylesheet named app/global.css: body {
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}Inside the root layout (app/layout.js), import the global.css stylesheet to apply the styles to every route in your application:app/layout.tsx // These styles apply to every route in the application


import './global.css'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (

      {children}

  )
}
External Stylesheets
Stylesheets published by external packages can be imported anywhere in the app directory, including colocated components:app/layout.tsx import 'bootstrap/dist/css/bootstrap.css'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (

      {children}

  )
}
Good to know: External stylesheets must be directly imported from an npm package or downloaded and colocated with your codebase. You cannot use <link rel="stylesheet" />.
Additional Features


Additional Features
Next.js includes additional features to improve the authoring experience of adding styles:
When running locally with next dev, local stylesheets (either global or CSS modules) will take advantage of Fast Refresh to instantly reflect changes as edits are saved.
When building for production with next build, CSS files will be bundled into fewer minified .css files to reduce the number of network requests needed to retrieve styles.
If you disable JavaScript, styles will still be loaded in the production build (next start). However, JavaScript is still required for next dev to enable Fast Refresh.


Tailwind CSS
Tailwind CSS is a utility-first CSS framework that works exceptionally well with Next.js.
Installing Tailwind
Install the Tailwind CSS packages and run the init command to generate both the tailwind.config.js and postcss.config.js files:
Terminal npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Configuring Tailwind
Inside tailwind.config.js, add paths to the files that will use Tailwind CSS class names:
tailwind.config.js /** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory.
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',


'./components/**/*.{js,ts,jsx,tsx,mdx}',

    // Or if using `src` directory:
    './src/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
You do not need to modify postcss.config.js.
Importing Styles
Add the Tailwind CSS directives that Tailwind will use to inject its generated styles to a Global Stylesheet in your application, for example:app/globals.css @tailwind base;
@tailwind components;
@tailwind utilities;Inside the root layout (app/layout.tsx), import the globals.css stylesheet to apply the styles to every route in your application.app/layout.tsx import type { Metadata } from 'next'

// These styles apply to every route in the application
import './globals.css'


// These styles apply to every route in the application
import './globals.css'

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (

      {children}

  )
}Using Classes
After installing Tailwind CSS and adding the global styles, you can use Tailwind's utility classes in your application.app/page.tsx export default function Page() {
  return
Hello, Next.js!

}
Usage with Turbopack
As of Next.js 13.1, Tailwind CSS and PostCSS are supported with Turbopack.


Sass
Next.js has built-in support for Sass using both the .scss and .sass extensions. You can use component-level Sass via CSS Modules and the .module.scssor .module.sass extension.
First, install sass:
Terminal npm install --save-dev sass
Good to know:
Sass supports two different syntax, each with their own extension.
The .scss extension requires you use the SCSS syntax,
while the .sass extension requires you use the Indented Syntax ("Sass").
If you're not sure which to choose, start with the .scss extension which is a superset of CSS, and doesn't require you learn the
Indented Syntax ("Sass").
Customizing Sass Options
If you want to configure the Sass compiler, use sassOptions in next.config.js.
next.config.js const path = require('path')

module.exports = {
  sassOptions: {


module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
}
Sass Variables
Next.js supports Sass variables exported from CSS Module files.
For example, using the exported primaryColor Sass variable:
app/variables.module.scss $primary-color: #64ff00;

:export {
  primaryColor: $primary-color;
}
app/page.js // maps to root `/` URL

import variables from './variables.module.scss'

export default function Page() {
  return
Hello, Next.js!

}


CSS-in-JS
Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React, including concurrent rendering.
We're working with the React team on upstream APIs to handle CSS and JavaScript assets with support for React Server Components and streaming architecture.
The following libraries are supported in Client Components in the app directory (alphabetical):
kuma-ui
@mui/material
pandacss
styled-jsx
styled-components
style9
tamagui
tss-react
vanilla-extract
The following are currently working on support:
emotion
Good to know: We're testing out different CSS-in-JS libraries and we'll be adding more examples for libraries that support React 18 features and/or the app directory.


If you want to style Server Components, we recommend using CSS Modules or other solutions that output CSS files, like PostCSS or Tailwind CSS.Configuring CSS-in-JS in app
Configuring CSS-in-JS is a three-step opt-in process that involves:
A style registry to collect all CSS rules in a render.
The new useServerInsertedHTML hook to inject rules before any content that might use them.
A Client Component that wraps your app with the style registry during initial server-side rendering.
styled-jsx
Using styled-jsx in Client Components requires using v5.1.0. First, create a new registry:app/registry.tsx 'use client'

import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'

export default function StyledJsxRegistry({
  children,


export default function StyledJsxRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [jsxStyleRegistry] = useState(() => createStyleRegistry())

  useServerInsertedHTML(() => {
    const styles = jsxStyleRegistry.styles()
    jsxStyleRegistry.flush()
    return <>{styles}</>
  })

  return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}Then, wrap your root layout with the registry:app/layout.tsx import StyledJsxRegistry from './registry'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>


}) {
  return (
    <html>
      <body>
        <StyledJsxRegistry>{children}</StyledJsxRegistry>
      </body>
    </html>
  )
}View an example here.Styled Components
Below is an example of how to configure styled-components@v6.0.0-rc.1 or greater:First, use the styled-components API to create a global registry component to collect all CSS style rules generated during a render, and a function to return those rules. Then use the useServerInsertedHTML hook to inject the styles collected in the registry into the <head> HTML tag in the root layout.lib/registry.tsx 'use client'

import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'

export default function StyledComponentsRegistry({


export default function StyledComponentsRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())

  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement()
    styledComponentsStyleSheet.instance.clearTag()
    return <>{styles}</>
  })

  if (typeof window !== 'undefined') return <>{children}</>

  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  )
}Wrap the children of the root layout with the style registry component:app/layout.tsx import StyledComponentsRegistry from './lib/registry'


export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
      </body>
    </html>
  )
}View an example here.
Good to know:
During server rendering, styles will be extracted to a global registry and flushed to the <head> of your HTML. This ensures the style rules are placed before any content that might use them. In the future, we may use an upcoming React feature to determine where to inject the styles.
During streaming, styles from each chunk will be collected and appended to existing styles. After client-side hydration is complete, styled-components will take over as usual and inject any further dynamic styles.


We specifically use a Client Component at the top level of the tree for the style registry because it's more efficient to extract CSS rules this way. It avoids re-generating styles on subsequent server renders, and prevents them from being sent in the Server Component payload.


CodemodsCodemods are transformations that run on your codebase programmatically. This allows a large number of changes to be programmatically applied without having to manually go through every file.
Next.js provides Codemod transformations to help upgrade your Next.js codebase when an API is updated or deprecated.
Usage
In your terminal, navigate (cd) into your project's folder, then run:
Terminal npx @next/codemod <transform> <path>
Replacing <transform> and <path> with appropriate values.
transform - name of transform
path - files or directory to transform
--dry Do a dry-run, no code will be edited
--print Prints the changed output for comparison
Next.js Codemods
13.2
Use Built-in Font
built-in-next-font
Terminal npx @next/codemod@latest built-in-next-font .


Terminal npx @next/codemod@latest built-in-next-font .
This codemod uninstalls the @next/font package and transforms @next/font imports into the built-in next/font.
For example:
 import { Inter } from '@next/font/google'
Transforms into:
 import { Inter } from 'next/font/google'
13.0
Rename Next Image Imports
next-image-to-legacy-image
Terminal npx @next/codemod@latest next-image-to-legacy-image .
Safely renames next/image imports in existing Next.js 10, 11, or 12 applications to next/legacy/image in Next.js 13. Also renames next/future/image to next/image.
For example:
pages/index.js import Image1 from 'next/image'
import Image2 from 'next/future/image'

export default function Home() {
  return (
    <div>


export default function Home() {
  return (

      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />

  )
}
Transforms into:
pages/index.js // 'next/image' becomes 'next/legacy/image'
import Image1 from 'next/legacy/image'
// 'next/future/image' becomes 'next/image'
import Image2 from 'next/image'

export default function Home() {
  return (

      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />

  )
}
Migrate to the New Image Component
next-image-experimental


)
}
Migrate to the New Image Component
next-image-experimental
Terminal npx @next/codemod@latest next-image-experimental .
Dangerously migrates from next/legacy/image to the new next/image by adding inline styles and removing unused props.
Removes layout prop and adds style.
Removes objectFit prop and adds style.
Removes objectPosition prop and adds style.
Removes lazyBoundary prop.
Removes lazyRoot prop.
Remove  Tags From Link Components
new-link
Terminal npx @next/codemod@latest new-link .
Remove  tags inside Link Components, or add a legacyBehavior prop to Links that cannot be auto-fixed.
For example:
 <Link href="/about">
  About
</Link>
// transforms into
<Link href="/about">
  About
</Link>

<Link href="/about">


About
</Link>

<Link href="/about">
   console.log('clicked')}>About
</Link>
// transforms into
<Link href="/about" onClick={() => console.log('clicked')}>
  About
</Link>
In cases where auto-fixing can't be applied, the legacyBehavior prop is added. This allows your app to keep functioning using the old behavior for that particular link.
 const Component = () => About

<Link href="/about">
  <Component />
</Link>
// becomes
<Link href="/about" legacyBehavior>
  <Component />
</Link>
11
Migrate from CRA
cra-to-next
Terminal npx @next/codemod cra-to-next


cra-to-next
Terminal npx @next/codemod cra-to-next
Migrates a Create React App project to Next.js; creating a Pages Router and necessary config to match behavior. Client-side only rendering is leveraged initially to prevent breaking compatibility due to window usage during SSR and can be enabled seamlessly to allow the gradual adoption of Next.js specific features.
Please share any feedback related to this transform in this discussion.
10
Add React imports
add-missing-react-import
Terminal npx @next/codemod add-missing-react-import
Transforms files that do not import React to include the import in order for the new React JSX transform to work.
For example:
my-component.js export default class Home extends React.Component {
  render() {
    return
Hello World

  }
}
Transforms into:
my-component.js import React from 'react'
export default class Home extends React.Component {


my-component.js import React from 'react'
export default class Home extends React.Component {
  render() {
    return
Hello World

  }
}
9
Transform Anonymous Components into Named Components
name-default-component
Terminal npx @next/codemod name-default-component
Versions 9 and above.
Transforms anonymous components into named components to make sure they work with Fast Refresh.
For example:
my-component.js export default function () {
  return
Hello World

}
Transforms into:
my-component.js export default function MyComponent() {
  return
Hello World

}
The component will have a camel-cased name based on the name of the file, and it also works with arrow functions.
8
Transform AMP HOC into page config
withamp-to-config
Terminal npx @next/codemod withamp-to-config


withamp-to-config
Terminal npx @next/codemod withamp-to-config
Transforms the withAmp HOC into Next.js 9 page configuration.
For example:
 // Before
import { withAmp } from 'next/amp'

function Home() {
  return
My AMP Page

}

export default withAmp(Home)
 // After
export default function Home() {
  return
My AMP Page

}

export const config = {
  amp: true,
}
6
Use withRouter
url-to-withrouter
Terminal npx @next/codemod url-to-withrouter
Transforms the deprecated automatically injected url property on top level pages to using withRouter and the router property it injects. Read more here: https://nextjs.org/docs/messages/url-deprecated
For example:


For example:
From import React from 'react'
export default class extends React.Component {
  render() {
    const { pathname } = this.props.url
    return
Current pathname: {pathname}

  }
}
To import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
  class extends React.Component {
    render() {
      const { pathname } = this.props.router
      return
Current pathname: {pathname}

    }
  }
)
This is one case. All the cases that are transformed (and tested) can be found in the __testfixtures__ directory.