gavmac00/nextjs-app-docs huggingface dataset:
app
└── dashboard
    ├── layout.tsx
    ├── settings
    │   └── page.tsx
    └── analytics
        └── page.js
When navigating from /dashboard/settings to /dashboard/analytics, page.tsx in /dashboard/analytics will be rendered on the server because it is UI that changed, while dashboard/layout.tsx will not be re-rendered because it is a common UI between the two routes.
This performance optimization allows navigation between pages that share a layout to be quicker as only the data fetching and rendering for the page has to run, instead of the entire route that could include shared layouts that fetch their own data.
Because dashboard/layout.tsx doesn't re-render, the searchParams prop in the layout Server Component might become stale after navigation.
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.
Root Layouts
The app directory must include a root app/layout.js.
The root layout must define <html> and <body> tags.
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.
You can use route groups to create multiple root layouts.
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.
Version History
VersionChangesv13.0.0layout introduced.
error.jsAn error file defines an error UI boundary for a route segment.
It is useful for catching unexpected errors that occur in Server Components and Client Components and displaying a fallback UI.
app/dashboard/error.tsx 'use client' // Error components must be Client Components
 
import { useEffect } from 'react'
 
export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Log the error to an error reporting service
    console.error(error)
  }, [error])
 
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Attempt to recover by trying to re-render the segment
          () => reset()
        }
      >
        Try again
      </button>
}
      >
        Try again
      </button>
    </div>
  )
}
Props
error
An instance of an Error object forwarded to the error.js Client Component.
error.message
The error message.
For errors forwarded from Client Components, this will be the original Error's message.
For errors forwarded from Server Components, this will be a generic error message to avoid leaking sensitive details. errors.digest can be used to match the corresponding error in server-side logs.
error.digest
An automatically generated hash of the error thrown in a Server Component. It can be used to match the corresponding error in server-side logs.
reset
A function to reset the error boundary. When executed, the function will try to re-render the Error boundary's contents. If successful, the fallback error component is replaced with the result of the re-render.
Can be used to prompt the user to attempt to recover from the error.
Can be used to prompt the user to attempt to recover from the error.
Good to know:
error.js boundaries must be Client Components.
In Production builds, errors forwarded from Server Components will be stripped of specific error details to avoid leaking sensitive information.
An error.js boundary will not handle errors thrown in a layout.js component in the same segment because the error boundary is nested inside that layouts component.
To handle errors for a specific layout, place an error.js file in the layouts parent segment.
To handle errors within the root layout or template, use a variation of error.js called app/global-error.js.
global-error.js
To specifically handle errors in root layout.js, use a variation of error.js called app/global-error.js located in the root app directory.
app/global-error.tsx 'use client'
 
export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  )
}
Good to know:
global-error.js replaces the root layout.js when active and so must define its own <html> and <body> tags.
While designing error UI, you may find it helpful to use the React Developer Tools to manually toggle Error boundaries.
Version History
VersionChangesv13.1.0global-error introduced.v13.0.0error introduced.
route.jsRoute Handlers allow you to create custom request handlers for a given route using the Web Request and Response APIs.
HTTP Methods
A route file allows you to create custom request handlers for a given route. The following HTTP methods are supported: GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS.
route.ts export async function GET(request: Request) {}
 
export async function HEAD(request: Request) {}
 
export async function POST(request: Request) {}
 
export async function PUT(request: Request) {}
 
export async function DELETE(request: Request) {}
 
export async function PATCH(request: Request) {}
 
// If `OPTIONS` is not defined, Next.js will automatically implement `OPTIONS` and  set the appropriate Response `Allow` header depending on the other methods defined in the route handler.
export async function OPTIONS(request: Request) {}
export async function OPTIONS(request: Request) {}
Good to know: Route Handlers are only available inside the app directory. You do not need to use API Routes (pages) and Route Handlers (app) together, as Route Handlers should be able to handle all use cases.
Parameters
request (optional)
The request object is a NextRequest object, which is an extension of the Web Request API. NextRequest gives you further control over the incoming request, including easily accessing cookies and an extended, parsed, URL object nextUrl.
context (optional)
app/dashboard/[team]/route.js export async function GET(request, context: { params }) {
  const team = params.team // '1'
}
Currently, the only value of context is params, which is an object containing the dynamic route parameters for the current route.
ExampleURLparamsapp/dashboard/[team]/route.js/dashboard/1{ team: '1' }app/shop/[tag]/[item]/route.js/shop/1/2{ tag: '1', item: '2' }app/blog/[...slug]/route.js/blog/1/2{ slug: ['1', '2'] }
NextResponse
Route Handlers can extend the Web Response API by returning a NextResponse object. This allows you to easily set cookies, headers, redirect, and rewrite. View the API reference.
Version History
VersionChangesv13.2.0Route handlers are introduced.
template.jsThis documentation is still being written. Please check back later.
sitemap.xmlAdd or generate a sitemap.xml file that matches the Sitemaps XML format in the root of app directory to help search engine crawlers crawl your site more efficiently.
Static sitemap.xml
app/sitemap.xml <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acme.com</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
  <url>
    <loc>https://acme.com/about</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
  <url>
    <loc>https://acme.com/blog</loc>
<url>
    <loc>https://acme.com/blog</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
</urlset>
Generate a Sitemap
Add a sitemap.js or sitemap.ts file that returns Sitemap.
app/sitemap.ts import { MetadataRoute } from 'next'
 
export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: 'https://acme.com',
      lastModified: new Date(),
    },
    {
      url: 'https://acme.com/about',
      lastModified: new Date(),
    },
    {
      url: 'https://acme.com/blog',
      lastModified: new Date(),
    },
  ]
}
Output:
lastModified: new Date(),
    },
  ]
}
Output:
acme.com/sitemap.xml <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acme.com</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
  <url>
    <loc>https://acme.com/about</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
  <url>
    <loc>https://acme.com/blog</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
  </url>
</urlset>
</url>
</urlset>
Sitemap Return Type
 type Sitemap = Array<{
  url: string
  lastModified?: string | Date
}>
Good to know
In the future, we will support multiple sitemaps and sitemap indexes.
Version History
VersionChangesv13.3.0sitemap introduced.
opengraph-image and twitter-imageThe opengraph-image and twitter-image file conventions allow you to set Open Graph and Twitter images for a route segment.
They are useful for setting the images that appear on social networks and messaging apps when a user shares a link to your site.
There are two ways to set Open Graph and Twitter images:
Using image files (.jpg, .png, .gif)
Using code to generate images (.js, .ts, .tsx)
Image files (.jpg, .png, .gif)
Use an image file to set a route segment's shared image by placing an opengraph-image or twitter-image image file in the segment.
Next.js will evaluate the file and automatically add the appropriate tags to your app's <head> element.
File conventionSupported file typesopengraph-image.jpg, .jpeg, .png, .giftwitter-image.jpg, .jpeg, .png, .gifopengraph-image.alt.txttwitter-image.alt.txt
opengraph-image
Add an opengraph-image.(jpg|jpeg|png|gif) image file to any route segment.
<head> output <meta property="og:image" content="<generated>" />
<meta property="og:image:type" content="<generated>" />
<meta property="og:image:width" content="<generated>" />
<meta property="og:image:height" content="<generated>" />
twitter-image
Add a twitter-image.(jpg|jpeg|png|gif) image file to any route segment.
<head> output <meta name="twitter:image" content="<generated>" />
<meta name="twitter:image:type" content="<generated>" />
<meta name="twitter:image:width" content="<generated>" />
<meta name="twitter:image:width" content="<generated>" />
<meta name="twitter:image:height" content="<generated>" />
opengraph-image.alt.txt
Add an accompanying opengraph-image.alt.txt file in the same route segment as the opengraph-image.(jpg|jpeg|png|gif) image it's alt text.
opengraph-image.alt.txt About Acme
<head> output <meta property="og:image:alt" content="About Acme" />
twitter-image.alt.txt
Add an accompanying twitter-image.alt.txt file in the same route segment as the twitter-image.(jpg|jpeg|png|gif) image it's alt text.
twitter-image.alt.txt About Acme
<head> output <meta property="og:image:alt" content="About Acme" />
Generate images using code (.js, .ts, .tsx)
In addition to using literal image files, you can programmatically generate images using code.
In addition to using literal image files, you can programmatically generate images using code.
Generate a route segment's shared image by creating an opengraph-image or twitter-image route that default exports a function.
File conventionSupported file typesopengraph-image.js, .ts, .tsxtwitter-image.js, .ts, .tsx
Good to know
By default, generated images are statically optimized (generated at build time and cached) unless they use dynamic functions or dynamic data fetching.
You can generate multiple Images in the same file using generateImageMetadata.
The easiest way to generate an image is to use the ImageResponse API from next/server.
app/about/opengraph-image.tsx import { ImageResponse } from 'next/server'
 
// Route segment config
export const runtime = 'edge'
 
// Image metadata
export const alt = 'About Acme'
export const size = {
  width: 1200,
export const size = {
  width: 1200,
  height: 630,
}
 
export const contentType = 'image/png'
 
// Font
const interSemiBold = fetch(
  new URL('./Inter-SemiBold.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
 
// Image generation
export default async function Image() {
  return new ImageResponse(
    (
      // ImageResponse JSX element
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        About Acme
      </div>
    ),
    // ImageResponse options
    {
</div>
    ),
    // ImageResponse options
    {
      // For convenience, we can re-use the exported opengraph-image
      // size config to also set the ImageResponse's width and height.
      ...size,
      fonts: [
        {
          name: 'Inter',
          data: await interSemiBold,
          style: 'normal',
          weight: 400,
        },
      ],
    }
  )
}
<head> output <meta property="og:image" content="<generated>" />
<meta property="og:image:alt" content="About Acme" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
Props
The default export function receives the following props:
params (optional)
Props
The default export function receives the following props:
params (optional)
An object containing the dynamic route parameters object from the root segment down to the segment opengraph-image or twitter-image is colocated in.
app/shop/[slug]/opengraph-image.tsx export default function Image({ params }: { params: { slug: string } }) {
  // ...
}
RouteURLparamsapp/shop/opengraph-image.js/shopundefinedapp/shop/[slug]/opengraph-image.js/shop/1{ slug: '1' }app/shop/[tag]/[item]/opengraph-image.js/shop/1/2{ tag: '1', item: '2' }app/shop/[...slug]/opengraph-image.js/shop/1/2{ slug: ['1', '2'] }
Returns
The default export function should return a Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response.
Good to know: ImageResponse satisfies this return type.
Config exports
You can optionally configure the image's metadata by exporting alt, size, and contentType variables from opengraph-image or twitter-image route.
OptionTypealtstringsize{ width: number; height: number }contentTypestring - image MIME type
alt
opengraph-image.tsx / twitter-image.tsx export const alt = 'My images alt text'
 
export default function Image() {}
<head> output <meta property="og:image:alt" content="My images alt text" />
size
opengraph-image.tsx / twitter-image.tsx export const size = { width: 1200, height: 630 }
 
export default function Image() {}
<head> output <meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
contentType
<meta property="og:image:height" content="630" />
contentType
opengraph-image.tsx / twitter-image.tsx export const contentType = 'image/png'
 
export default function Image() {}
<head> output <meta property="og:image:type" content="image/png" />
Route Segment Config
opengraph-image and twitter-image are specialized Route Handlers that can use the same route segment configuration options as Pages and Layouts.
OptionTypeDefaultdynamic'auto' | 'force-dynamic' | 'error' | 'force-static''auto'revalidatefalse | 'force-cache' | 0 | numberfalseruntime'nodejs' | 'edge''nodejs'preferredRegion'auto' | 'global' | 'home' | string | string[]'auto'
app/opengraph-image.tsx export const runtime = 'edge'
 
export default function Image() {}
Examples
Using external data
export default function Image() {}
Examples
Using external data
This example uses the params object and external data to generate the image.
Good to know:
By default, this generated image will be statically optimized. You can configure the individual fetch options or route segments options to change this behavior.
app/posts/[slug]/opengraph-image.tsx import { ImageResponse } from 'next/server'
 
export const runtime = 'edge'
 
export const alt = 'About Acme'
export const size = {
  width: 1200,
  height: 630,
}
export const contentType = 'image/png'
 
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await fetch(`https://.../posts/${params.slug}`).then((res) =>
    res.json()
  )
 
  return new ImageResponse(
res.json()
  )
 
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 48,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    ),
    {
      ...size,
    }
  )
}
Version History
VersionChangesv13.3.0opengraph-image and twitter-image introduced.
favicon, icon, and apple-iconThe favicon, icon, or apple-icon file conventions allow you to set icons for your application.
They are useful for adding app icons that appear in places like web browser tabs, phone home screens, and search engine results.
There are two ways to set app icons:
Using image files (.ico, .jpg, .png)
Using code to generate an icon (.js, .ts, .tsx)
Image files (.ico, .jpg, .png)
Use an image file to set an app icon by placing a favicon, icon, or apple-icon image file within your /app directory.
The favicon image can only be located in the top level of app/.
Next.js will evaluate the file and automatically add the appropriate tags to your app's <head> element.
File conventionSupported file typesValid locationsfavicon.icoapp/icon.ico, .jpg, .jpeg, .png, .svgapp/**/*apple-icon.jpg, .jpeg, .pngapp/**/*
favicon
Add a favicon.ico image file to the root /app route segment.
<head> output <link rel="icon" href="/favicon.ico" sizes="any" />
icon
Add an icon.(ico|jpg|jpeg|png|svg) image file.
<head> output <link
  rel="icon"
  href="/icon?<generated>"
  type="image/<generated>"
  sizes="<generated>"
/>
apple-icon
Add an apple-icon.(jpg|jpeg|png) image file.
<head> output <link
  rel="apple-touch-icon"
  href="/apple-icon?<generated>"
  type="image/<generated>"
  sizes="<generated>"
/>
Good to know
type="image/<generated>"
  sizes="<generated>"
/>
Good to know
You can set multiple icons by adding a number suffix to the file name. For example, icon1.png, icon2.png, etc. Numbered files will sort lexically.
Favicons can only be set in the root /app segment. If you need more granularity, you can use icon.
The appropriate <link> tags and attributes such as rel, href, type, and sizes are determined by the icon type and metadata of the evaluated file.
For example, a 32 by 32px .png file will have type="image/png" and sizes="32x32" attributes.
sizes="any" is added to favicon.ico output to avoid a browser bug where an .ico icon is favored over .svg.
Generate icons using code (.js, .ts, .tsx)
Generate icons using code (.js, .ts, .tsx)
In addition to using literal image files, you can programmatically generate icons using code.
Generate an app icon by creating an icon or apple-icon route that default exports a function.
File conventionSupported file typesicon.js, .ts, .tsxapple-icon.js, .ts, .tsx
The easiest way to generate an icon is to use the ImageResponse API from next/server.
app/icon.tsx import { ImageResponse } from 'next/server'
 
// Route segment config
export const runtime = 'edge'
 
// Image metadata
export const size = {
  width: 32,
  height: 32,
}
export const contentType = 'image/png'
 
// Image generation
export default function Icon() {
  return new ImageResponse(
    (
      // ImageResponse JSX element
      <div
        style={{
(
      // ImageResponse JSX element
      <div
        style={{
          fontSize: 24,
          background: 'black',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          color: 'white',
        }}
      >
        A
      </div>
    ),
    // ImageResponse options
    {
      // For convenience, we can re-use the exported icons size metadata
      // config to also set the ImageResponse's width and height.
      ...size,
    }
  )
}
<head> output <link rel="icon" href="/icon?<generated>" type="image/png" sizes="32x32" />
Good to know
Good to know
By default, generated icons are statically optimized (generated at build time and cached) unless they use dynamic functions or dynamic data fetching.
You can generate multiple icons in the same file using generateImageMetadata.
You cannot generate a favicon icon. Use icon or a favicon.ico file instead.
Props
The default export function receives the following props:
params (optional)
An object containing the dynamic route parameters object from the root segment down to the segment icon or apple-icon is colocated in.
app/shop/[slug]/icon.tsx export default function Icon({ params }: { params: { slug: string } }) {
  // ...
}
// ...
}
RouteURLparamsapp/shop/icon.js/shopundefinedapp/shop/[slug]/icon.js/shop/1{ slug: '1' }app/shop/[tag]/[item]/icon.js/shop/1/2{ tag: '1', item: '2' }app/shop/[...slug]/icon.js/shop/1/2{ slug: ['1', '2'] }
Returns
The default export function should return a Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response.
Good to know: ImageResponse satisfies this return type.
Config exports
You can optionally configure the icon's metadata by exporting size and contentType variables from the icon or apple-icon route.
OptionTypesize{ width: number; height: number }contentTypestring - image MIME type
size
icon.tsx / apple-icon.tsx export const size = { width: 32, height: 32 }
 
export default function Icon() {}
export default function Icon() {}
<head> output <link rel="icon" sizes="32x32" />
contentType
icon.tsx / apple-icon.tsx export const contentType = 'image/png'
 
export default function Icon() {}
<head> output <link rel="icon" type="image/png" />
Route Segment Config
icon and apple-icon are specialized Route Handlers that can use the same route segment configuration options as Pages and Layouts.
OptionTypeDefaultdynamic'auto' | 'force-dynamic' | 'error' | 'force-static''auto'revalidatefalse | 'force-cache' | 0 | numberfalseruntime'nodejs' | 'edge''nodejs'preferredRegion'auto' | 'global' | 'home' | string | string[]'auto'
app/icon.tsx export const runtime = 'edge'
 
export default function Icon() {}
Version History
export default function Icon() {}
Version History
VersionChangesv13.3.0favicon icon and apple-icon introduced
robots.txtAdd or generate a robots.txt file that matches the Robots Exclusion Standard in the root of app directory to tell search engine crawlers which URLs they can access on your site.
Static robots.txt
app/robots.txt User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://acme.com/sitemap.xml
Generate a Robots file
Add a robots.js or robots.ts file that returns a Robots object.
app/robots.ts import { MetadataRoute } from 'next'
 
export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/private/',
    },
    sitemap: 'https://acme.com/sitemap.xml',
  }
}
Output:
 User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://acme.com/sitemap.xml
Disallow: /private/
Sitemap: https://acme.com/sitemap.xml
Robots object
 type Robots = {
  rules:
    | {
        userAgent?: string | string[]
        allow?: string | string[]
        disallow?: string | string[]
        crawlDelay?: number
      }
    | Array<{
        userAgent: string | string[]
        allow?: string | string[]
        disallow?: string | string[]
        crawlDelay?: number
      }>
  sitemap?: string | string[]
  host?: string
}
Version History
VersionChangesv13.3.0robots introduced.