gavmac00/nextjs-app-docs huggingface dataset:
const search = searchParams.get('search')
 
  // This will not be logged on the server when using static rendering
  console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx import { Suspense } from 'react'
import SearchBar from './search-bar'
 
// This component passed as a fallback to the Suspense boundary
// will be rendered in place of the search bar in the initial HTML.
// When the value is available during React hydration the fallback
// will be replaced with the `<SearchBar>` component.
function SearchBarFallback() {
  return <>placeholder</>
}
 
export default function Page() {
  return (
    <>
      <nav>
        <Suspense fallback={<SearchBarFallback />}>
          <SearchBar />
        </Suspense>
      </nav>
<SearchBar />
        </Suspense>
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}
Dynamic Rendering
If a route is dynamically rendered, useSearchParams will be available on the server during the initial server render of the Client Component.
Good to know: Setting the dynamic route segment config option to force-dynamic can be used to force dynamic rendering.
For example:
app/dashboard/search-bar.tsx 'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // This will be logged on the server during the initial render
  // and on the client on subsequent navigations.
  console.log(search)
 
  return <>Search: {search}</>
}
console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx import SearchBar from './search-bar'
 
export const dynamic = 'force-dynamic'
 
export default function Page() {
  return (
    <>
      <nav>
        <SearchBar />
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}
Server Components
Pages
To access search params in Pages (Server Components), use the searchParams prop.
Layouts
Unlike Pages, Layouts (Server Components) do not receive the searchParams prop. This is because a shared layout is not re-rendered during navigation which could lead to stale searchParams between navigations. View detailed explanation.
Instead, use the Page searchParams prop or the useSearchParams hook in a Client Component, which is re-rendered on the client with the latest searchParams.
Examples
Updating searchParams
You can use useRouter or Link to set new searchParams. After a navigation is performed, the current page.js will receive an updated searchParams prop.
app/example-client-component.tsx export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()!
 
  // Get a new searchParams string by merging the current
  // searchParams with a provided key/value pair
  const createQueryString = useCallback(
    (name: string, value: string) => {
      const params = new URLSearchParams(searchParams)
      params.set(name, value)
 
      return params.toString()
    },
    [searchParams]
  )
return params.toString()
    },
    [searchParams]
  )
 
  return (
    <>
      <p>Sort By</p>
 
      {/* using useRouter */}
      <button
        onClick={() => {
          // <pathname>?sort=asc
          router.push(pathname + '?' + createQueryString('sort', 'asc'))
        }}
      >
        ASC
      </button>
 
      {/* using <Link> */}
      <Link
        href={
          // <pathname>?sort=desc
          pathname + '?' + createQueryString('sort', 'desc')
        }
      >
        DESC
      </Link>
    </>
  )
}
Version History
VersionChangesv13.0.0useSearchParams introduced.
headersThe headers function allows you to read the HTTP incoming request headers from a Server Component.
headers()
This API extends the Web Headers API. It is read-only, meaning you cannot set / delete the outgoing request headers.
app/page.tsx import { headers } from 'next/headers'
 
export default function Page() {
  const headersList = headers()
  const referer = headersList.get('referer')
 
  return <div>Referer: {referer}</div>
}
Good to know:
headers() is a Dynamic Function whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into dynamic rendering at request time.
API Reference
 const headersList = headers()
Parameters
headers does not take any parameters.
Returns
headers returns a read-only Web Headers object.
Headers.entries(): Returns an iterator allowing to go through all key/value pairs contained in this object.
Headers.entries(): Returns an iterator allowing to go through all key/value pairs contained in this object.
Headers.forEach(): Executes a provided function once for each key/value pair in this Headers object.
Headers.get(): Returns a String sequence of all the values of a header within a Headers object with a given name.
Headers.has(): Returns a boolean stating whether a Headers object contains a certain header.
Headers.keys(): Returns an iterator allowing you to go through all keys of the key/value pairs contained in this object.
Headers.values(): Returns an iterator allowing you to go through all values of the key/value pairs contained in this object.
Examples
Usage with Data Fetching
headers() can be used in combination with Suspense for Data Fetching.
app/page.js import { headers } from 'next/headers'
 
async function getUser() {
  const headersInstance = headers()
  const authorization = headersInstance.get('authorization')
  // Forward the authorization header
const authorization = headersInstance.get('authorization')
  // Forward the authorization header
  const res = await fetch('...', {
    headers: { authorization },
  })
  return res.json()
}
 
export default async function UserPage() {
  const user = await getUser()
  return <h1>{user.name}</h1>
}
Version History
VersionChangesv13.0.0headers introduced.
ImageResponseThe ImageResponse constructor allows you to generate dynamic images using JSX and CSS. This is useful for generating social media images such as Open Graph images, Twitter cards, and more.
The following options are available for ImageResponse:
 import { ImageResponse } from 'next/server'
 
new ImageResponse(
  element: ReactElement,
  options: {
    width?: number = 1200
    height?: number = 630
    emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' = 'twemoji',
    fonts?: {
      name: string,
      data: ArrayBuffer,
      weight: number,
      style: 'normal' | 'italic'
    }[]
    debug?: boolean = false
 
    // Options that will be passed to the HTTP response
    status?: number = 200
    statusText?: string
status?: number = 200
    statusText?: string
    headers?: Record<string, string>
  },
)
Supported CSS Properties
Please refer to Satori’s documentation for a list of supported HTML and CSS features.
Version History
VersionChangesv13.3.0ImageResponse can be imported from next/server.v13.0.0ImageResponse introduced via @vercel/og package.
notFoundThe notFound function allows you to render the not-found file within a route segment as well as inject a <meta name="robots" content="noindex" /> tag.
notFound()
Invoking the notFound() function throws a NEXT_NOT_FOUND error and terminates rendering of the route segment in which it was thrown. Specifying a not-found file allows you to gracefully handle such errors by rendering a Not Found UI within the segment.
app/user/[id]/page.js import { notFound } from 'next/navigation'
 
async function fetchUser(id) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
export default async function Profile({ params }) {
  const user = await fetchUser(params.id)
 
  if (!user) {
    notFound()
  }
 
  // ...
}
notFound()
  }
 
  // ...
}
Good to know: notFound() does not require you to use return notFound() due to using the TypeScript never type.
Version History
VersionChangesv13.0.0notFound introduced.
Metadata Object and generateMetadata OptionsThis page covers all Config-based Metadata options with generateMetadata and the static metadata object.
layout.tsx / page.tsx import { Metadata } from 'next'
 
// either Static metadata
export const metadata: Metadata = {
  title: '...',
}
 
// or Dynamic metadata
export async function generateMetadata({ params }) {
  return {
    title: '...',
  }
}
Good to know:
The metadata object and generateMetadata function exports are only supported in Server Components.
You cannot export both the metadata object and generateMetadata function from the same route segment.
The metadata object
To define static metadata, export a Metadata object from a layout.js or page.js file.
layout.tsx / page.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: '...',
  description: '...',
}
title: '...',
  description: '...',
}
 
export default function Page() {}
See the Metadata Fields for a complete list of supported options.
generateMetadata function
Dynamic metadata depends on dynamic information, such as the current route parameters, external data, or metadata in parent segments, can be set by exporting a generateMetadata function that returns a Metadata object.
app/products/[id]/page.tsx import { Metadata, ResolvingMetadata } from 'next'
 
type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}
 
export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  // read route params
  const id = params.id
 
  // fetch data
// read route params
  const id = params.id
 
  // fetch data
  const product = await fetch(`https://.../${id}`).then((res) => res.json())
 
  // optionally access and extend (rather than replace) parent metadata
  const previousImages = (await parent).openGraph?.images || []
 
  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  }
}
 
export default function Page({ params, searchParams }: Props) {}
Parameters
generateMetadata function accepts the following parameters:
props - An object containing the parameters of the current route:
params - An object containing the dynamic route parameters object from the root segment down to the segment generateMetadata is called from. Examples:
RouteURLparamsapp/shop/[slug]/page.js/shop/1{ slug: '1' }app/shop/[tag]/[item]/page.js/shop/1/2{ tag: '1', item: '2' }app/shop/[...slug]/page.js/shop/1/2{ slug: ['1', '2'] }
searchParams - An object containing the current URL's search params. Examples:
URLsearchParams/shop?a=1{ a: '1' }/shop?a=1&b=2{ a: '1', b: '2' }/shop?a=1&a=2{ a: ['1', '2'] }
parent - A promise of the resolved metadata from parent route segments.
Returns
generateMetadata should return a Metadata object containing one or more metadata fields.
Good to know:
generateMetadata should return a Metadata object containing one or more metadata fields.
Good to know:
If metadata doesn't depend on runtime information, it should be defined using the static metadata object rather than generateMetadata.
When rendering a route, Next.js will automatically deduplicate fetch requests for the same data across generateMetadata, generateStaticParams, Layouts, Pages, and Server Components. React cache can be used if fetch is unavailable.
searchParams are only available in page.js segments.
The redirect() and notFound() Next.js methods can also be used inside generateMetadata.
Metadata Fields
title
The title attribute is used to set the title of the document. It can be defined as a simple string or an optional template object.
String
layout.js / page.js export const metadata = {
  title: 'Next.js',
}
<head> output <title>Next.js</title>
Template object
}
<head> output <title>Next.js</title>
Template object
app/layout.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    template: '...',
    default: '...',
    absolute: '...',
  },
}
Default
title.default can be used to provide a fallback title to child route segments that don't define a title.
app/layout.tsx import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    default: 'Acme',
  },
}
app/about/page.tsx import type { Metadata } from 'next'
 
export const metadata: Metadata = {}
 
// Output: <title>Acme</title>
Template
title.template can be used to add a prefix or a suffix to titles defined in child route segments.
app/layout.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // a default is required when creating a template
  },
}
app/about/page.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'About',
}
 
// Output: <title>About | Acme</title>
Good to know:
title.template applies to child route segments and not the segment it's defined in. This means:
title.default is required when you add a title.template.
title.template defined in layout.js will not apply to a title defined in a page.js of the same route segment.
title.template defined in page.js has no effect because a page is always the terminating segment (it doesn't have any children route segments).
title.template has no effect if a route has not defined a title or title.default.
Absolute
title.absolute can be used to provide a title that ignores title.template set in parent segments.
app/layout.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
  },
}
app/about/page.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    absolute: 'About',
  },
}
 
// Output: <title>About</title>
Good to know:
layout.js
title (string) and title.default define the default title for child segments (that do not define their own title). It will augment title.template from the closest parent segment if it exists.
title.absolute defines the default title for child segments. It ignores title.template from parent segments.
title.absolute defines the default title for child segments. It ignores title.template from parent segments.
title.template defines a new title template for child segments.
page.js
If a page does not define its own title the closest parents resolved title will be used.
title (string) defines the routes title. It will augment title.template from the closest parent segment if it exists.
title.absolute defines the route title. It ignores title.template from parent segments.
title.template has no effect in page.js because a page is always the terminating segment of a route.
description
layout.js / page.js export const metadata = {
  description: 'The React Framework for the Web',
}
<head> output <meta name="description" content="The React Framework for the Web" />
Basic Fields
layout.js / page.js export const metadata = {
  generator: 'Next.js',
  applicationName: 'Next.js',
generator: 'Next.js',
  applicationName: 'Next.js',
  referrer: 'origin-when-cross-origin',
  keywords: ['Next.js', 'React', 'JavaScript'],
  authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
  colorScheme: 'dark',
  creator: 'Jiachi Liu',
  publisher: 'Sebastian Markbåge',
  formatDetection: {
    email: false,
    address: false,
    telephone: false,
  },
}
<head> output <meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />
metadataBase
metadataBase is a convenience option to set a base URL prefix for metadata fields that require a fully qualified URL.
metadataBase allows URL-based metadata fields defined in the current route segment and below to use a relative path instead of an otherwise required absolute URL.
The field's relative path will be composed with metadataBase to form a fully qualified URL.
If not configured, metadataBase is automatically populated with a default value.
If not configured, metadataBase is automatically populated with a default value.
layout.js / page.js export const metadata = {
  metadataBase: new URL('https://acme.com'),
  alternates: {
    canonical: '/',
    languages: {
      'en-US': '/en-US',
      'de-DE': '/de-DE',
    },
  },
  openGraph: {
    images: '/og-image.png',
  },
}
<head> output <link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />
Good to know:
Good to know:
metadataBase is typically set in root app/layout.js to apply to URL-based metadata fields across all routes.
All URL-based metadata fields that require absolute URLs can be configured with a metadataBase option.
metadataBase can contain a subdomain e.g. https://app.acme.com or base path e.g. https://acme.com/start/from/here
If a metadata field provides an absolute URL, metadataBase will be ignored.
Using a relative path in a URL-based metadata field without configuring a metadataBase will cause a build error.
Next.js will normalize duplicate slashes between metadataBase (e.g. https://acme.com/) and a relative field (e.g. /path) to a single slash (e.g. https://acme.com/path)
Default value
If not configured, metadataBase has a default value
Default value
If not configured, metadataBase has a default value
When VERCEL_URL is detected: https://${process.env.VERCEL_URL} otherwise it falls back to http://localhost:${process.env.PORT || 3000}.
When overriding the default, we recommend using environment variables to compute the URL. This allows configuring a URL for local development, staging, and production environments.
URL Composition
URL composition favors developer intent over default directory traversal semantics.
Trailing slashes between metadataBase and metadata fields are normalized.
An "absolute" path in a metadata field (that typically would replace the whole URL path) is treated as a "relative" path (starting from the end of metadataBase).
For example, given the following metadataBase:
app/layout.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  metadataBase: new URL('https://acme.com'),
}
metadataBase: new URL('https://acme.com'),
}
Any metadata fields that inherit the above metadataBase and set their own value will be resolved as follows:
metadata fieldResolved URL/https://acme.com./https://acme.compaymentshttps://acme.com/payments/paymentshttps://acme.com/payments./paymentshttps://acme.com/payments../paymentshttps://acme.com/paymentshttps://beta.acme.com/paymentshttps://beta.acme.com/payments
openGraph
layout.js / page.js export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'The React Framework for the Web',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png',
        width: 800,
width: 800,
        height: 600,
      },
      {
        url: 'https://nextjs.org/og-alt.png',
        width: 1800,
        height: 1600,
        alt: 'My custom alt',
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
}
<head> output <meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image:url" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="My custom alt" />
<meta property="og:type" content="website" />
layout.js / page.js export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'The React Framework for the Web',
    type: 'article',
    publishedTime: '2023-01-01T00:00:00.000Z',
    authors: ['Seb', 'Josh'],
  },
}
authors: ['Seb', 'Josh'],
  },
}
<head> output <meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />
Good to know:
It may be more convenient to use the file-based Metadata API for Open Graph images. Rather than having to sync the config export with actual files, the file-based API will automatically generate the correct metadata for you.
robots
 import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  robots: {
    index: false,
export const metadata: Metadata = {
  robots: {
    index: false,
    follow: true,
    nocache: true,
    googleBot: {
      index: true,
      follow: false,
      noimageindex: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
}
<head> output <meta name="robots" content="noindex, follow, nocache" />
<meta
  name="googlebot"
  content="index, nofollow, noimageindex, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>
icons
/>
icons
Good to know: We recommend using the file-based Metadata API for icons where possible. Rather than having to sync the config export with actual files, the file-based API will automatically generate the correct metadata for you.
layout.js / page.js export const metadata = {
  icons: {
    icon: '/icon.png',
    shortcut: '/shortcut-icon.png',
    apple: '/apple-icon.png',
    other: {
      rel: 'apple-touch-icon-precomposed',
      url: '/apple-touch-icon-precomposed.png',
    },
  },
}
<head> output <link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
href="/apple-touch-icon-precomposed.png"
/>
layout.js / page.js export const metadata = {
  icons: {
    icon: [{ url: '/icon.png' }, new URL('/icon.png', 'https://example.com')],
    shortcut: ['/shortcut-icon.png'],
    apple: [
      { url: '/apple-icon.png' },
      { url: '/apple-icon-x3.png', sizes: '180x180', type: 'image/png' },
    ],
    other: [
      {
        rel: 'apple-touch-icon-precomposed',
        url: '/apple-touch-icon-precomposed.png',
      },
    ],
  },
}
<head> output <link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
<link rel="icon" href="https://example.com/icon.png" />
<link
  rel="apple-touch-icon"
  href="/apple-icon-x3.png"
  sizes="180x180"
  type="image/png"
/>
Good to know: The msapplication-* meta tags are no longer supported in Chromium builds of Microsoft Edge, and thus no longer needed.
themeColor
Learn more about theme-color.
Simple theme color
layout.js / page.js export const metadata = {
  themeColor: 'black',
}
<head> output <meta name="theme-color" content="black" />
With media attribute
layout.js / page.js export const metadata = {
  themeColor: [