gavmac00/nextjs-app-docs huggingface dataset:
layout.js / page.js export const metadata = {
  themeColor: [
    { media: '(prefers-color-scheme: light)', color: 'cyan' },
    { media: '(prefers-color-scheme: dark)', color: 'black' },
  ],
}
<head> output <meta name="theme-color" media="(prefers-color-scheme: light)" content="cyan" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />
manifest
A web application manifest, as defined in the Web Application Manifest specification.
layout.js / page.js export const metadata = {
  manifest: 'https://nextjs.org/manifest.json',
}
<head> output <link rel="manifest" href="https://nextjs.org/manifest.json" />
twitter
Learn more about the Twitter Card markup reference.
layout.js / page.js export const metadata = {
layout.js / page.js export const metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'Next.js',
    description: 'The React Framework for the Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: ['https://nextjs.org/og.png'],
  },
}
<head> output <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
layout.js / page.js export const metadata = {
  twitter: {
    card: 'app',
    title: 'Next.js',
    description: 'The React Framework for the Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: {
      url: 'https://nextjs.org/og.png',
      alt: 'Next.js Logo',
    },
    app: {
      name: 'twitter_app',
      id: {
        iphone: 'twitter_app://iphone',
        ipad: 'twitter_app://ipad',
ipad: 'twitter_app://ipad',
        googleplay: 'twitter_app://googleplay',
      },
      url: {
        iphone: 'https://iphone_url',
        ipad: 'https://ipad_url',
      },
    },
  },
}
<head> output <meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />
viewport
<meta name="twitter:app:name:googleplay" content="twitter_app" />
viewport
Good to know: The viewport meta tag is automatically set with the following default values. Usually, manual configuration is unnecessary as the default is sufficient. However, the information is provided for completeness.
layout.js / page.js export const metadata = {
  viewport: {
    width: 'device-width',
    initialScale: 1,
    maximumScale: 1,
  },
}
<head> output <meta
  name="viewport"
  content="width=device-width, initial-scale=1, maximum-scale=1"
/>
verification
layout.js / page.js export const metadata = {
  verification: {
    google: 'google',
    yandex: 'yandex',
    yahoo: 'yahoo',
    other: {
      me: ['my-email', 'my-link'],
    },
  },
me: ['my-email', 'my-link'],
    },
  },
}
<head> output <meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />
appleWebApp
layout.js / page.js export const metadata = {
  itunes: {
    appId: 'myAppStoreID',
    appArgument: 'myAppArgument',
  },
  appleWebApp: {
    title: 'Apple Web App',
    statusBarStyle: 'black-translucent',
    startupImage: [
      '/assets/startup/apple-touch-startup-image-768x1004.png',
      {
{
        url: '/assets/startup/apple-touch-startup-image-1536x2008.png',
        media: '(device-width: 768px) and (device-height: 1024px)',
      },
    ],
  },
}
<head> output <meta
  name="apple-itunes-app"
  content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Apple Web App" />
<link
  href="/assets/startup/apple-touch-startup-image-768x1004.png"
  rel="apple-touch-startup-image"
/>
<link
  href="/assets/startup/apple-touch-startup-image-1536x2008.png"
href="/assets/startup/apple-touch-startup-image-1536x2008.png"
  media="(device-width: 768px) and (device-height: 1024px)"
  rel="apple-touch-startup-image"
/>
<meta
  name="apple-mobile-web-app-status-bar-style"
  content="black-translucent"
/>
alternates
layout.js / page.js export const metadata = {
  alternates: {
    canonical: 'https://nextjs.org',
    languages: {
      'en-US': 'https://nextjs.org/en-US',
      'de-DE': 'https://nextjs.org/de-DE',
    },
    media: {
      'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
    },
    types: {
      'application/rss+xml': 'https://nextjs.org/rss',
types: {
      'application/rss+xml': 'https://nextjs.org/rss',
    },
  },
}
<head> output <link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
  rel="alternate"
  media="only screen and (max-width: 600px)"
  href="https://nextjs.org/mobile"
/>
<link
  rel="alternate"
  type="application/rss+xml"
  href="https://nextjs.org/rss"
/>
appLinks
layout.js / page.js export const metadata = {
  appLinks: {
    ios: {
      url: 'https://nextjs.org/ios',
ios: {
      url: 'https://nextjs.org/ios',
      app_store_id: 'app_store_id',
    },
    android: {
      package: 'com.example.android/package',
      app_name: 'app_name_android',
    },
    web: {
      url: 'https://nextjs.org/web',
      should_fallback: true,
    },
  },
}
<head> output <meta property="al:ios:url" content="https://nextjs.org/ios" />
<meta property="al:ios:app_store_id" content="app_store_id" />
<meta property="al:android:package" content="com.example.android/package" />
<meta property="al:android:app_name" content="app_name_android" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:should_fallback" content="true" />
archives
Describes a collection of records, documents, or other materials of historical interest (source).
layout.js / page.js export const metadata = {
  archives: ['https://nextjs.org/13'],
}
<head> output <link rel="archives" href="https://nextjs.org/13" />
assets
layout.js / page.js export const metadata = {
  assets: ['https://nextjs.org/assets'],
}
<head> output <link rel="assets" href="https://nextjs.org/assets" />
bookmarks
layout.js / page.js export const metadata = {
  bookmarks: ['https://nextjs.org/13'],
}
bookmarks: ['https://nextjs.org/13'],
}
<head> output <link rel="bookmarks" href="https://nextjs.org/13" />
category
layout.js / page.js export const metadata = {
  category: 'technology',
}
<head> output <meta name="category" content="technology" />
other
All metadata options should be covered using the built-in support. However, there may be custom metadata tags specific to your site, or brand new metadata tags just released. You can use the other option to render any custom metadata tag.
layout.js / page.js export const metadata = {
  other: {
    custom: 'meta',
  },
}
<head> output <meta name="custom" content="meta" />
Unsupported Metadata
The following metadata types do not currently have built-in support. However, they can still be rendered in the layout or page itself.
MetadataRecommendation<meta http-equiv="...">Use appropriate HTTP Headers via redirect(), Middleware, Security Headers<base>Render the tag in the layout or page itself.<noscript>Render the tag in the layout or page itself.<style>Learn more about styling in Next.js.<script>Learn more about using scripts.<link rel="stylesheet" />import stylesheets directly in the layout or page itself.<link rel="preload />Use ReactDOM preload method<link rel="preconnect" />Use ReactDOM preconnect method<link rel="dns-prefetch" />Use ReactDOM prefetchDNS method
Resource hints
The <link> element has a number of rel keywords that can be used to hint to the browser that a external resource is likely to be needed. The browser uses this information to apply preloading optimizations depending on the keyword.
While the Metadata API doesn't directly support these hints, you can use new ReactDOM methods to safely insert them into the <head> of the document.
app/preload-resources.tsx 'use client'
 
import ReactDOM from 'react-dom'
 
export function PreloadResources() {
  ReactDOM.preload('...', { as: '...' })
  ReactDOM.preconnect('...', { crossOrigin: '...' })
  ReactDOM.prefetchDNS('...')
 
  return null
}
<link rel="preload">
Start loading a resource early in the page rendering (browser) lifecycle. MDN Docs.
 ReactDOM.preload(href: string, options: { as: string })
<head> output <link rel="preload" href="..." as="..." />
<link rel="preconnect">
Preemptively initiate a connection to an origin. MDN Docs.
 ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<head> output <link rel="preconnect" href="..." crossorigin />
<link rel="dns-prefetch">
<link rel="dns-prefetch">
Attempt to resolve a domain name before resources get requested. MDN Docs.
 ReactDOM.prefetchDNS(href: string)
<head> output <link rel="dns-prefetch" href="..." />
Good to know:
These methods are currently only supported in Client Components, which are still Server Side Rendered on initial page load.
Next.js in-built features such as next/font, next/image and next/script automatically handle relevant resource hints.
React 18.3 does not yet include type definitions for ReactDOM.preload, ReactDOM.preconnect, and ReactDOM.preconnectDNS. You can use // @ts-ignore as a temporary solution to avoid type errors.
Types
You can add type safety to your metadata by using the Metadata type. If you are using the built-in TypeScript plugin in your IDE, you do not need to manually add the type, but you can still explicitly add it if you want.
metadata object
metadata object
 import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'Next.js',
}
generateMetadata function
Regular function
 import type { Metadata } from 'next'
 
export function generateMetadata(): Metadata {
  return {
    title: 'Next.js',
  }
}
Async function
 import type { Metadata } from 'next'
 
export async function generateMetadata(): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}
With segment props
 import type { Metadata } from 'next'
 
type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}
 
export function generateMetadata({ params, searchParams }: Props): Metadata {
  return {
    title: 'Next.js',
return {
    title: 'Next.js',
  }
}
 
export default function Page({ params, searchParams }: Props) {}
With parent metadata
 import type { Metadata, ResolvingMetadata } from 'next'
 
export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}
JavaScript Projects
For JavaScript projects, you can use JSDoc to add type safety.
 /** @type {import("next").Metadata} */
export const metadata = {
  title: 'Next.js',
}
Version History
VersionChangesv13.2.0metadata and generateMetadata introduced.
revalidateTagrevalidateTag allows you to revalidate data associated with a specific cache tag. This is useful for scenarios where you want to update your cached data without waiting for a revalidation period to expire.
app/api/revalidate/route.ts import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'
 
export async function GET(request: NextRequest) {
  const tag = request.nextUrl.searchParams.get('tag')
  revalidateTag(tag)
  return NextResponse.json({ revalidated: true, now: Date.now() })
}
Good to know:
revalidateTag is available in both Node.js and Edge runtimes.
Parameters
 revalidateTag(tag: string): void;
tag: A string representing the cache tag associated with the data you want to revalidate.
You can add tags to fetch as follows:
You can add tags to fetch as follows:
 fetch(url, { next: { tags: [...] } });
Returns
revalidateTag does not return any value.
Examples
Node.js Runtime
app/api/revalidate/route.ts import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'
 
export async function GET(request: NextRequest) {
  const tag = request.nextUrl.searchParams.get('tag')
  revalidateTag(tag)
  return NextResponse.json({ revalidated: true, now: Date.now() })
}
Edge Runtime
app/api/revalidate/route.ts import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'
 
export const runtime = 'edge'
 
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() })
}
useReportWebVitals
The useReportWebVitals hook allows you to report Core Web Vitals, and can be used in combination with your analytics service.
app/_components/web-vitals.js 'use client'
 
import { useReportWebVitals } from 'next/web-vitals'
 
export function WebVitals() {
  useReportWebVitals((metric) => {
    console.log(metric)
  })
}app/layout.js import { WebVitals } from './_components/web-vitals'
 
export default function Layout({ children }) {
  return (
    <html>
      <body>
        <WebVitals />
        {children}
      </body>
    </html>
  )
}
{children}
      </body>
    </html>
  )
}
Since the useReportWebVitals hook requires the "use client" directive, the most performant approach is to create a separate component that the root layout imports. This confines the client boundary exclusively to the WebVitals component.
useReportWebVitals
The metric object passed as the hook's argument consists of a number of properties:
id: Unique identifier for the metric in the context of the current page load
name: The name of the performance metric. Possible values include names of Web Vitals metrics (TTFB, FCP, LCP, FID, CLS) specific to a web application.
delta: The difference between the current value and the previous value of the metric. The value is typically in milliseconds and represents the change in the metric's value over time.
entries: An array of Performance Entries associated with the metric. These entries provide detailed information about the performance events related to the metric.
navigationType: Indicates the type of navigation that triggered the metric collection. Possible values include "navigate", "reload", "back_forward", and "prerender".
rating: A qualitative rating of the metric value, providing an assessment of the performance. Possible values are "good", "needs-improvement", and "poor". The rating is typically determined by comparing the metric value against predefined thresholds that indicate acceptable or suboptimal performance.
value: The actual value or duration of the performance entry, typically in milliseconds. The value provides a quantitative measure of the performance aspect being tracked by the metric. The source of the value depends on the specific metric being measured and can come from various Performance APIs.
Web Vitals
Web Vitals are a set of useful metrics that aim to capture the user
Web Vitals
Web Vitals are a set of useful metrics that aim to capture the user
experience of a web page. The following web vitals are all included:
Time to First Byte (TTFB)
First Contentful Paint (FCP)
Largest Contentful Paint (LCP)
First Input Delay (FID)
Cumulative Layout Shift (CLS)
Interaction to Next Paint (INP)
You can handle all the results of these metrics using the name property.
app/components/web-vitals.tsx 'use client'
 
import { useReportWebVitals } from 'next/web-vitals'
 
export function WebVitals() {
  useReportWebVitals((metric) => {
    switch (metric.name) {
      case 'FCP': {
        // handle FCP results
      }
      case 'LCP': {
        // handle LCP results
}
      case 'LCP': {
        // handle LCP results
      }
      // ...
    }
  })
}
Usage on Vercel
Vercel Speed Insights are automatically configured on Vercel deployments, and don't require the use of useReportWebVitals. This hook is useful in local development, or if you're using a different analytics service.
Sending results to external systems
You can send results to any endpoint to measure and track
real user performance on your site. For example:
 useReportWebVitals((metric) => {
  const body = JSON.stringify(metric)
  const url = 'https://example.com/analytics'
 
  // Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
  if (navigator.sendBeacon) {
    navigator.sendBeacon(url, body)
  } else {
navigator.sendBeacon(url, body)
  } else {
    fetch(url, { body, method: 'POST', keepalive: true })
  }
})
Good to know: If you use Google Analytics, using the
id value can allow you to construct metric distributions manually (to calculate percentiles,
etc.)
 useReportWebVitals(metric => {
  // Use `window.gtag` if you initialized Google Analytics as this example:
  // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js
  window.gtag('event', metric.name, {
    value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value), // values must be integers
    event_label: metric.id, // id unique to current page load
    non_interaction: true, // avoids affecting bounce rate.
  });
}
non_interaction: true, // avoids affecting bounce rate.
  });
}
Read more about sending results to Google Analytics.
NextRequestNextRequest extends the Web Request API with additional convenience methods.
cookies
Read or mutate the Set-Cookie header of the request.
set(name, value)
Given a name, set a cookie with the given value on the request.
 // Given incoming request /home
// Set a cookie to hide the banner
// request will have a `Set-Cookie:show-banner=false;path=/home` header
request.cookies.set('show-banner', 'false')
get(name)
Given a cookie name, return the value of the cookie. If the cookie is not found, undefined is returned. If multiple cookies are found, the first one is returned.
 // Given incoming request /home
// { name: 'show-banner', value: 'false', Path: '/home' }
request.cookies.get('show-banner')
getAll()
request.cookies.get('show-banner')
getAll()
Given a cookie name, return the values of the cookie. If no name is given, return all cookies on the request.
 // Given incoming request /home
// [
//   { name: 'experiments', value: 'new-pricing-page', Path: '/home' },
//   { name: 'experiments', value: 'winter-launch', Path: '/home' },
// ]
request.cookies.getAll('experiments')
// Alternatively, get all cookies for the request
request.cookies.getAll()
delete(name)
Given a cookie name, delete the cookie from the request.
 // Returns true for deleted, false is nothing is deleted
request.cookies.delete('experiments')
has(name)
Given a cookie name, return true if the cookie exists on the request.
 // Returns true if cookie exists, false if it does not
request.cookies.has('experiments')
clear()
request.cookies.has('experiments')
clear()
Remove the Set-Cookie header from the request.
 request.cookies.clear()
nextUrl
Extends the native URL API with additional convenience methods, including Next.js specific properties.
 // Given a request to /home, pathname is /home
request.nextUrl.pathname
// Given a request to /home?name=lee, searchParams is { 'name': 'lee' }
request.nextUrl.searchParams
Version History
VersionChangesv13.0.0useSearchParams introduced.
cookiesThe cookies function allows you to read the HTTP incoming request cookies from a Server Component or write outgoing request cookies in a Server Action or Route Handler.
Good to know: cookies() 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.
cookies().get(name)
A method that takes a cookie name and returns an object with name and value. If a cookie with name isn't found, it returns undefined. If multiple cookies match, it will only return the first match.
app/page.js import { cookies } from 'next/headers'
 
export default function Page() {
  const cookieStore = cookies()
  const theme = cookieStore.get('theme')
  return '...'
}
cookies().getAll()
return '...'
}
cookies().getAll()
A method that is similar to get, but returns a list of all the cookies with a matching name. If name is unspecified, it returns all the available cookies.
app/page.js import { cookies } from 'next/headers'
 
export default function Page() {
  const cookieStore = cookies()
  return cookieStore.getAll().map((cookie) => (
    <div key={cookie.name}>
      <p>Name: {cookie.name}</p>
      <p>Value: {cookie.value}</p>
    </div>
  ))
}
cookies().has(name)
A method that takes a cookie name and returns a boolean based on if the cookie exists (true) or not (false).
app/page.js import { cookies } from 'next/headers'
 
export default function Page() {
  const cookiesList = cookies()
export default function Page() {
  const cookiesList = cookies()
  const hasCookie = cookiesList.has('theme')
  return '...'
}
cookies().set(name, value, options)
A method that takes a cookie name, value, and options and sets the outgoing request cookie.
Good to know: .set() is only available in a Server Action or Route Handler.
app/actions.js 'use server'
 
import { cookies } from 'next/headers'
 
async function create(data) {
  cookies().set('name', 'lee')
  // or
  cookies().set('name', 'lee', { secure: true })
  // or
  cookies().set({
    name: 'name',
    value: 'lee',
    httpOnly: true,
    path: '/',
  })
}
Deleting cookies
httpOnly: true,
    path: '/',
  })
}
Deleting cookies
To "delete" a cookie, you must set a new cookie with the same name and an empty value. You can also set the maxAge to 0 to expire the cookie immediately.
Good to know: .set() is only available in a Server Action or Route Handler.
app/actions.js 'use server'
 
import { cookies } from 'next/headers'
 
async function create(data) {
  cookies().set({
    name: 'name',
    value: '',
    expires: new Date('2016-10-05'),
    path: '/', // For all paths
  })
}
You can only set cookies that belong to the same domain from which .set() is called. Additionally, the code must be executed on the same protocol (HTTP or HTTPS) as the cookie you want to update.
Version History
VersionChangesv13.0.0cookies introduced.
useSelectedLayoutSegmentsuseSelectedLayoutSegments is a Client Component hook that lets you read the active route segments below the Layout it is called from.
It is useful for creating UI in parent Layouts that need knowledge of active child segments such as breadcrumbs.
app/example-client-component.tsx 'use client'
 
import { useSelectedLayoutSegments } from 'next/navigation'
 
export default function ExampleClientComponent() {
  const segments = useSelectedLayoutSegments()
 
  return (
    <ul>
      {segments.map((segment, index) => (
        <li key={index}>{segment}</li>
      ))}
    </ul>
  )
}
Good to know:
Since useSelectedLayoutSegments is a Client Component hook, and Layouts are Server Components by default, useSelectedLayoutSegments is usually called via a Client Component that is imported into a Layout.