[
  {
    "url": "https://nextjs.org/docs",
    "title": "Next.js Docs | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Next.js Docs</h1><p>Welcome to the Next.js documentation!</p>\n<h2 id=\"what-is-nextjs\" data-docs-heading=\"\">What is Next.js?<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#what-is-nextjs\"><span></span></a></h2>\n<p>Next.js is a React framework for building full-stack web applications. You use React Components to build user interfaces, and Next.js for additional features and optimizations.</p>\n<p>It also automatically configures lower-level tools like bundlers and compilers. You can instead focus on building your product and shipping quickly.</p>\n<p>Whether you're an individual developer or part of a larger team, Next.js can help you build interactive, dynamic, and fast React applications.</p>\n<h2 id=\"how-to-use-the-docs\" data-docs-heading=\"\">How to use the docs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-to-use-the-docs\"><span></span></a></h2>\n<p>The docs are organized into 3 sections:</p>\n<ul>\n<li><a href=\"/docs/app/getting-started\">Getting Started</a>: Step-by-step tutorials to help you create a new application and learn the core Next.js features.</li>\n<li><a href=\"/docs/app/guides\">Guides</a>: Tutorials on specific use cases, choose what's relevant to you.</li>\n<li><a href=\"/docs/app/api-reference\">API Reference</a>: Detailed technical reference for every feature.</li>\n</ul>\n<p>Use the sidebar to navigate through the sections, or search (<code>Ctrl+K</code> or <code>Cmd+K</code>) to quickly find a page.</p>\n<h2 id=\"app-router-and-pages-router\" data-docs-heading=\"\">App Router and Pages Router<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#app-router-and-pages-router\"><span></span></a></h2>\n<p>Next.js has two different routers:</p>\n<ul>\n<li><strong>App Router</strong>: The newer router that supports new React features like Server Components.</li>\n<li><strong>Pages Router</strong>: The original router, still supported and being improved.</li>\n</ul>\n<p>At the top of the sidebar, you'll notice a dropdown menu that allows you to switch between the <a href=\"/docs/app\">App Router</a> and the <a href=\"/docs/pages\">Pages Router</a> docs.</p>\n<h3 id=\"react-version-handling\" data-docs-heading=\"\">React version handling<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#react-version-handling\"><span></span></a></h3>\n<p>The App Router and Pages Router handle React versions differently:</p>\n<ul>\n<li>\n<p><strong>App Router</strong>: Uses <a href=\"https://react.dev/blog/2023/05/03/react-canaries\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">React canary releases<span class=\"inline-flex not-prose\"></span></a> built-in, which include all the stable React 19 changes, as well as newer features being validated in frameworks, prior to a new React release.</p>\n</li>\n<li>\n<p><strong>Pages Router</strong>: Uses the React version installed in your project's <code>package.json</code>.</p>\n</li>\n</ul>\n<p>This approach ensures new React features work reliably in the App Router while maintaining backwards compatibility for existing Pages Router applications.</p>\n<h2 id=\"pre-requisite-knowledge\" data-docs-heading=\"\">Pre-requisite knowledge<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#pre-requisite-knowledge\"><span></span></a></h2>\n<p>Our documentation assumes some familiarity with web development. Before getting started, it'll help if you're comfortable with:</p>\n<ul>\n<li>HTML</li>\n<li>CSS</li>\n<li>JavaScript</li>\n<li>React</li>\n</ul>\n<p>If you're new to React or need a refresher, we recommend starting with our <a href=\"/learn/react-foundations\">React Foundations course</a>, and the <a href=\"/learn/dashboard-app\">Next.js Foundations course</a> that has you building an application as you learn.</p>\n<h2 id=\"accessibility\" data-docs-heading=\"\">Accessibility<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#accessibility\"><span></span></a></h2>\n<p>For the best experience when using a screen reader, we recommend using Firefox and NVDA, or Safari and VoiceOver.</p>\n<h2 id=\"join-our-community\" data-docs-heading=\"\">Join our Community<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#join-our-community\"><span></span></a></h2>\n<p>If you have questions about anything related to Next.js, you're always welcome to ask our community on <a href=\"https://github.com/vercel/next.js/discussions\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub Discussions<span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://discord.com/invite/bUG2bvbtHy\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Discord<span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://x.com/nextjs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">X (Twitter)<span class=\"inline-flex not-prose\"></span></a>, and <a href=\"https://www.reddit.com/r/nextjs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Reddit<span class=\"inline-flex not-prose\"></span></a>.</p></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"next-steps\" data-docs-heading=\"\">Next Steps</h2><div class=\"mt-2 text-gray-900\">Create your first application and learn the core Next.js features.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Getting Started</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to create full-stack web applications with the Next.js App Router.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app",
    "title": "Next.js Docs: App Router | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">App Router</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 30, 2025</div><p>The <strong>App Router</strong> is a file-system based router that uses React's latest features such as <a href=\"https://react.dev/reference/rsc/server-components\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Server Components<span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://react.dev/reference/react/Suspense\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Suspense<span class=\"inline-flex not-prose\"></span></a>, and <a href=\"https://react.dev/reference/rsc/server-functions\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Server Functions<span class=\"inline-flex not-prose\"></span></a>.</p></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"next-steps\" data-docs-heading=\"\">Next Steps</h2><div class=\"mt-2 text-gray-900\">Learn the fundamentals of building an App Router project, from installation to layouts, navigation, server and client components.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/installation\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Installation</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to create a new Next.js application with the `create-next-app` CLI, and set up TypeScript, ESLint, and Module Path Aliases.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/project-structure\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Project Structure</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn the folder and file conventions in Next.js, and how to organize your project.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/layouts-and-pages\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Layouts and Pages</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to create your first pages and layouts, and link between them with the Link component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/linking-and-navigating\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Linking and Navigating</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how the built-in navigation optimizations work, including prefetching, prerendering, and client-side navigation, and how to optimize navigation for dynamic routes and slow networks.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/server-and-client-components\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Server and Client Components</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how you can use React Server and Client Components to render parts of your application on the server or the client.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference",
    "title": "App Router: API Reference | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">API Reference</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Directives</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Directives are used to modify the behavior of your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Components</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for Next.js built-in components.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/file-conventions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">File-system conventions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for Next.js file-system conventions.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Functions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for Next.js Functions and Hooks.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Configuration</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to configure Next.js applications.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/cli\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">CLI</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the Next.js Command Line Interface (CLI) tools.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Adapters</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Build deployment adapters for Next.js platforms and infrastructure.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/edge\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Edge Runtime</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the Edge Runtime.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/turbopack\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Turbopack</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Turbopack is an incremental bundler optimized for JavaScript and TypeScript, written in Rust, and built into Next.js.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters",
    "title": "API Reference: Adapters | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Adapters</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 29, 2026</div><p>Use this section to build and validate deployment adapters that integrate with the Next.js build and runtime model.</p>\n<ul>\n<li><a href=\"/docs/app/api-reference/adapters/configuration\">Configuration</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/creating-an-adapter\">Creating an Adapter</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/api-reference\">API Reference</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/testing-adapters\">Testing Adapters</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/routing-with-next-routing\">Routing with <code>@next/routing</code></a></li>\n<li><a href=\"/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter\">Implementing PPR in an Adapter</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/runtime-integration\">Runtime Integration</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/invoking-entrypoints\">Invoking Entrypoints</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/output-types\">Output Types</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/routing-information\">Routing Information</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/use-cases\">Use Cases</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/immutable-static-assets\">Supporting Immutable Static Assets</a></li>\n</ul>\n</div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/configuration\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Configuration</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure `adapterPath` or `NEXT_ADAPTER_PATH` to use a custom deployment adapter.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/creating-an-adapter\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Creating an Adapter</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Create an adapter module that implements the `NextAdapter` interface.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/api-reference\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">API Reference</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Reference for `modifyConfig` and `onBuildComplete` in the `NextAdapter` interface.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/testing-adapters\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Testing Adapters</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Validate adapters with the Next.js compatibility test harness and custom lifecycle scripts.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/routing-with-next-routing\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Routing with @next/routing</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use `@next/routing` to apply Next.js route matching behavior in adapters.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Implementing PPR in an Adapter</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Implement Partial Prerendering support in an adapter using fallback output and cache hooks.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/runtime-integration\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Runtime Integration</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Understand how build-time adapters and runtime cache interfaces work together.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/invoking-entrypoints\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Invoking Entrypoints</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Invoke Node.js and Edge build entrypoints with adapter runtime context.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/output-types\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Output Types</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Reference for all build output types exposed to adapters.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/routing-information\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Routing Information</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Reference for routing phases and route fields exposed in `onBuildComplete`.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/use-cases\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Use Cases</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Common patterns and examples for deployment adapter implementations.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/adapters/immutable-static-assets\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Supporting Immutable Static Assets</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Support immutable static assets in an adapter</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/api-reference",
    "title": "Adapters: API Reference | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">API Reference</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 18, 2026</div><h2 id=\"async-modifyconfigconfig-context\" data-docs-heading=\"\"><code>async modifyConfig(config, context)</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#async-modifyconfigconfig-context\"><span></span></a></h2>\n<p>Called for any CLI command that loads the <code>next.config.js</code> file to allow modification of the configuration.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code>config</code>: The complete Next.js configuration object</li>\n<li><code>context.phase</code>: The current build phase (see <a href=\"/docs/app/api-reference/config/next-config-js#phase\">phases</a>)</li>\n<li><code>context.nextVersion</code>: Version of Next.js being used</li>\n<li><code>context.projectDir</code>: Absolute path to the Next.js project directory</li>\n</ul>\n<p><strong>Returns:</strong> The modified configuration object (can be async)</p>\n<h2 id=\"async-onbuildcompletecontext\" data-docs-heading=\"\"><code>async onBuildComplete(context)</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#async-onbuildcompletecontext\"><span></span></a></h2>\n<p>Called after the build process completes with detailed information about routes and outputs.</p>\n<p><strong>Parameters:</strong></p>\n<ul>\n<li><code>context.routing</code>: Object containing Next.js routing phases and metadata<!-- -->\n<ul>\n<li><code>routing.beforeMiddleware</code>: Routes executed before middleware (includes header and redirect handling)</li>\n<li><code>routing.beforeFiles</code>: Rewrite routes checked before filesystem route matching</li>\n<li><code>routing.afterFiles</code>: Rewrite routes checked after filesystem route matching</li>\n<li><code>routing.dynamicRoutes</code>: Dynamic route matching table</li>\n<li><code>routing.onMatch</code>: Routes applied after a successful match (for example immutable static asset cache headers)</li>\n<li><code>routing.fallback</code>: Final rewrite fallback routes</li>\n<li><code>routing.shouldNormalizeNextData</code>: Whether <code>/_next/data/&lt;buildId&gt;/...</code> URLs should be normalized during matching</li>\n<li><code>routing.rsc</code>: Route metadata used for React Server Components routing behavior</li>\n</ul>\n</li>\n<li><code>context.outputs</code>: Detailed information about all build outputs organized by type</li>\n<li><code>context.projectDir</code>: Absolute path to the Next.js project directory</li>\n<li><code>context.repoRoot</code>: Absolute path to the detected repository root</li>\n<li><code>context.distDir</code>: Absolute path to the build output directory</li>\n<li><code>context.config</code>: The final Next.js configuration (with <code>modifyConfig</code> applied)</li>\n<li><code>context.nextVersion</code>: Version of Next.js being used</li>\n<li><code>context.buildId</code>: Unique identifier for the current build</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/configuration",
    "title": "Adapters: Configuration | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Configuration</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 30, 2026</div><p>To use an adapter, specify the path to your adapter module in <code>adapterPath</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  adapterPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./my-adapter.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>Alternatively <code>NEXT_ADAPTER_PATH</code> can be set to enable zero-config usage in deployment platforms.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/creating-an-adapter",
    "title": "Adapters: Creating an Adapter | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Creating an Adapter</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 18, 2026</div><p>An adapter is a module that exports an object implementing the <code>NextAdapter</code> interface.</p>\n<p>The interface can be imported from the <code>next</code> package:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextAdapter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span></code></pre></div>\n<p>The interface is defined as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">type</span><span style=\"color:var(--shiki-token-function)\"> Route</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  source</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourceRegex</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  destination</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  headers</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-function)\"> Record</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  has</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-function)\"> RouteHas</span><span style=\"color:var(--shiki-color-text)\">[]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  missing</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-function)\"> RouteHas</span><span style=\"color:var(--shiki-color-text)\">[]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  status</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  priority</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-constant)\"> boolean</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> interface</span><span style=\"color:var(--shiki-token-function)\"> AdapterOutputs</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pages</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'PAGES'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  middleware</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-function)\"> AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'MIDDLEWARE'</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  appPages</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'APP_PAGE'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pagesApi</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'PAGES_API'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  appRoutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'APP_ROUTE'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  prerenders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'PRERENDER'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  staticFiles</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">AdapterOutput</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'STATIC_FILE'</span><span style=\"color:var(--shiki-color-text)\">]&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> interface</span><span style=\"color:var(--shiki-token-function)\"> NextAdapter</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  modifyConfig</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfigComplete</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ctx</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      phase</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> PHASE_TYPE</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      nextVersion</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      projectDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">NextConfigComplete</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-function)\"> NextConfigComplete</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  onBuildComplete</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> (ctx</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    routing</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      beforeMiddleware</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      beforeFiles</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      afterFiles</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      dynamicRoutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      onMatch</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      fallback</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      shouldNormalizeNextData</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> boolean</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      rsc</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> RoutesManifest</span><span style=\"color:var(--shiki-color-text)\">[</span><span style=\"color:var(--shiki-token-string-expression)\">'rsc'</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    outputs</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> AdapterOutputs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    projectDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    repoRoot</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    distDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfigComplete</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    nextVersion</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    buildId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> void</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"basic-adapter-structure\" data-docs-heading=\"\">Basic Adapter Structure<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#basic-adapter-structure\"><span></span></a></h2>\n<p>Here's a minimal adapter example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my-adapter.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextAdapter}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> adapter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my-custom-adapter'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> modifyConfig</span><span style=\"color:var(--shiki-color-text)\">(config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { phase }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Modify the Next.js config based on the build phase</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (phase </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> 'phase-production-build'</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        ...</span><span style=\"color:var(--shiki-color-text)\">config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Add your modifications</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> onBuildComplete</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    routing</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    outputs</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    projectDir</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    repoRoot</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    distDir</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    nextVersion</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    buildId</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Process the build output</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Build completed with'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">pages</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'pages'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Build ID:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> buildId)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Dynamic routes:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> routing</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">dynamicRoutes</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Access emitted output entries</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> page</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.pages) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Page:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> page</span><span style=\"color:var(--shiki-color-text)\">.pathname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'at'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> page</span><span style=\"color:var(--shiki-color-text)\">.filePath)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> apiRoute</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.pagesApi) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'API Route:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> apiRoute</span><span style=\"color:var(--shiki-color-text)\">.pathname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'at'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> apiRoute</span><span style=\"color:var(--shiki-color-text)\">.filePath)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> appPage</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.appPages) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'App Page:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> appPage</span><span style=\"color:var(--shiki-color-text)\">.pathname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'at'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> appPage</span><span style=\"color:var(--shiki-color-text)\">.filePath)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> prerender</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.prerenders) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Prerendered:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> prerender</span><span style=\"color:var(--shiki-color-text)\">.pathname)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> adapter</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/immutable-static-assets",
    "title": "Adapters: Supporting Immutable Static Assets | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Supporting Immutable Static Assets</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 20, 2026</div><p>See <a href=\"/docs/app/api-reference/config/next-config-js/supportsImmutableAssets\"><code>config.supportsImmutableAssets</code></a> for end-user-facing information about this feature.</p>\n<p>When <code>config.supportsImmutableAssets</code> is enabled, Next.js outputs immutable content-addressed static assets under the public path <code>/_next/static/immutable/*</code>. This prefix can be used to differentiate immutable static assets from non-immutable static assets at the CDN level.</p>\n<p>At runtime, these immutable static assets are requested without the <code>?dpl</code> query parameter and thus live in a shared namespace across deployments. You must ensure that these assets are immutable and not changed (even after a new deployment) or deleted (for as long as there are active deployments using them) . Next.js may use a truncated shorter content hash as the filename, so <code>outputs.staticFiles[].immutableHash</code> contains the full content hash which can be used to validate that no hash collision occurred.</p>\n<p>You can use <code>config.outputHashSalt</code> to set a salt for the content hashes, if you want to rotate the hashes for any reason (e.g. after a detected hash collision).</p>\n<p>Note that you need to continue supporting non-immutable static assets (which may change between deployments and continue to be requested with the <code>?dpl</code> query parameter), e.g. for the <code>public</code> folder or for older Next.js versions.</p>\n<h2 id=\"adapter-implementation\" data-docs-heading=\"\">Adapter Implementation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#adapter-implementation\"><span></span></a></h2>\n<p>You need to:</p>\n<ol>\n<li>In the <code>modifyConfig</code>, set the <code>config.supportsImmutableAssets</code> property to <code>true</code> (if it's not already set to <code>false</code> by the user) to signal that you support deploying immutable static assets, and</li>\n<li>In <code>onBuildComplete</code>, read the <code>outputs.staticFiles[].immutableHash</code> property to determine which static assets are immutable and have to be requested without the <code>?dpl</code> query parameter.</li>\n</ol>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my-adapter.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextAdapter}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> adapter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my-custom-adapter'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> modifyConfig</span><span style=\"color:var(--shiki-color-text)\">(config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { phase }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (phase </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> 'phase-production-build'</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      config</span><span style=\"color:var(--shiki-color-text)\">.supportsImmutableAssets </span><span style=\"color:var(--shiki-token-keyword)\">=</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Default to true, but allow users to opt-out</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        config</span><span style=\"color:var(--shiki-color-text)\">.supportsImmutableAssets </span><span style=\"color:var(--shiki-token-keyword)\">??</span><span style=\"color:var(--shiki-token-constant)\"> true</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Optionally, pass a salt for the content hashes</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // config.outputHashSalt = getSaltForCurrentProject()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> onBuildComplete</span><span style=\"color:var(--shiki-color-text)\">({ outputs }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> output</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.staticFiles) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">output</span><span style=\"color:var(--shiki-color-text)\">.immutableHash </span><span style=\"color:var(--shiki-token-keyword)\">!=</span><span style=\"color:var(--shiki-token-constant)\"> null</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // This has to be requestable at `output.pathname`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // even without the `?dpl` query parameter.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        uploadOrVerifyImmutableStaticAsset</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          output</span><span style=\"color:var(--shiki-color-text)\">.filePath</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          output</span><span style=\"color:var(--shiki-color-text)\">.pathname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          output</span><span style=\"color:var(--shiki-color-text)\">.immutableHash</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      } </span><span style=\"color:var(--shiki-token-keyword)\">else</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // This is a non-immutable static asset and will be requested with</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // the `?dpl` query parameter, scoped to the deployment.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        uploadStaticAsset</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">output</span><span style=\"color:var(--shiki-color-text)\">.filePath</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> output</span><span style=\"color:var(--shiki-color-text)\">.pathname)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Process other outputs....</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter",
    "title": "Adapters: Implementing PPR in an Adapter | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Implementing PPR in an Adapter</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 30, 2026</div><p>For partially prerendered app routes, <code>onBuildComplete</code> gives you the data needed to seed and resume PPR:</p>\n<ul>\n<li><code>outputs.prerenders[].fallback.filePath</code>: path to the generated fallback shell (for example HTML)</li>\n<li><code>outputs.prerenders[].fallback.postponedState</code>: serialized postponed state used to resume rendering</li>\n</ul>\n<h2 id=\"1-seed-shell--postponed-state-at-build-time\" data-docs-heading=\"\">1. Seed shell + postponed state at build time<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#1-seed-shell--postponed-state-at-build-time\"><span></span></a></h2>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my-adapter.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { readFile } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'node:fs/promises'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> seedPprEntries</span><span style=\"color:var(--shiki-color-text)\">(outputs</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> AdapterOutputs</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> prerender</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-token-constant)\"> outputs</span><span style=\"color:var(--shiki-color-text)\">.prerenders) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> prerender</span><span style=\"color:var(--shiki-color-text)\">.fallback</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">!</span><span style=\"color:var(--shiki-token-constant)\">fallback</span><span style=\"color:var(--shiki-color-text)\">?.filePath </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-keyword)\"> !</span><span style=\"color:var(--shiki-token-constant)\">fallback</span><span style=\"color:var(--shiki-color-text)\">.postponedState) </span><span style=\"color:var(--shiki-token-keyword)\">continue</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> shell</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> readFile</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">fallback</span><span style=\"color:var(--shiki-color-text)\">.filePath</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'utf8'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    await</span><span style=\"color:var(--shiki-token-constant)\"> platformCache</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">prerender</span><span style=\"color:var(--shiki-color-text)\">.pathname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      shell</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      postponedState</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-color-text)\">.postponedState</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      initialHeaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-color-text)\">.initialHeaders</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      initialStatus</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-color-text)\">.initialStatus</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      initialRevalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-color-text)\">.initialRevalidate</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      initialExpiration</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> fallback</span><span style=\"color:var(--shiki-color-text)\">.initialExpiration</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"2-runtime-flow-serve-cached-shell-and-resume-in-background\" data-docs-heading=\"\">2. Runtime flow: serve cached shell and resume in background<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#2-runtime-flow-serve-cached-shell-and-resume-in-background\"><span></span></a></h2>\n<p>At request time, you can stream a single response that is the concatenation of:</p>\n<ol>\n<li>cached HTML shell stream</li>\n<li>resumed render stream (generated after invoking <code>handler</code> with postponed state)</li>\n</ol>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>Client</span></span>\n<span class=\"line\" data-line=\"\"><span>  | GET /ppr-route</span></span>\n<span class=\"line\" data-line=\"\"><span>  v</span></span>\n<span class=\"line\" data-line=\"\"><span>Adapter Router</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- read cached shell + postponedState ---&gt; Platform Cache</span></span>\n<span class=\"line\" data-line=\"\"><span>  |&lt;------------- cache hit -----------------|</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- create responseStream = concat(shellStream, resumedStream)</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- start piping shellStream ------------&gt; Client (first bytes)</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- invoke handler(req, res, { requestMeta: { postponed } })</span></span>\n<span class=\"line\" data-line=\"\"><span>  |   -------------------------------------&gt; Entrypoint (handler)</span></span>\n<span class=\"line\" data-line=\"\"><span>  |   &lt;------------------------------------- resumed chunks/cache entry</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- append resumed chunks to resumedStream</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  '-- client receives one HTTP response:</span></span>\n<span class=\"line\" data-line=\"\"><span>      [shell bytes........][resumed bytes........]</span></span></code></pre></div>\n<h2 id=\"3-update-cache-with-requestmetaoncacheentryv2\" data-docs-heading=\"\">3. Update cache with <code>requestMeta.onCacheEntryV2</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#3-update-cache-with-requestmetaoncacheentryv2\"><span></span></a></h2>\n<p><code>requestMeta.onCacheEntryV2</code> is called when a response cache entry is looked up or generated. Use it to persist updated shell/postponed data.</p>\n<div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none border-gray-alpha-400 text-gray-alpha-900 selection:bg-gray-alpha-900 dark-theme:selection:text-gray-1000 [&amp;_a:not([data-geist-button])]:text-gray-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1 not-prose\" data-slot=\"note-content\"><ul>\n<li><code>requestMeta.onCacheEntry</code> still works, but is deprecated.</li>\n<li>Prefer <code>requestMeta.onCacheEntryV2</code>.</li>\n<li>If your adapter uses an internal <code>onCacheCallback</code> abstraction, wire it to <code>requestMeta.onCacheEntryV2</code>.</li>\n</ul></div></div></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my-adapter.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-token-function)\"> handler</span><span style=\"color:var(--shiki-color-text)\">(req</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> res</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  waitUntil</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  requestMeta</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    postponed</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> cachedPprEntry</span><span style=\"color:var(--shiki-color-text)\">?.postponedState</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    onCacheEntryV2</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> (cacheEntry</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> meta) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">?.kind </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> 'APP_PAGE'</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        const</span><span style=\"color:var(--shiki-token-constant)\"> html</span><span style=\"color:var(--shiki-token-keyword)\"> =</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">.html </span><span style=\"color:var(--shiki-token-keyword)\">&amp;&amp;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          typeof</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">html</span><span style=\"color:var(--shiki-color-text)\">.toUnchunkedString </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> 'function'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">            ?</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">html</span><span style=\"color:var(--shiki-token-function)\">.toUnchunkedString</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">            :</span><span style=\"color:var(--shiki-token-constant)\"> null</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        await</span><span style=\"color:var(--shiki-token-constant)\"> platformCache</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">meta</span><span style=\"color:var(--shiki-color-text)\">.url </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> req</span><span style=\"color:var(--shiki-color-text)\">.url </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          shell</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> html</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          postponedState</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">.postponed</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">.headers</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          status</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-color-text)\">.status</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          cacheControl</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> cacheEntry</span><span style=\"color:var(--shiki-color-text)\">.cacheControl</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Return true only if your adapter already wrote the response itself.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>Entrypoint (handler)</span></span>\n<span class=\"line\" data-line=\"\"><span>  | onCacheEntryV2(cacheEntry, { url })</span></span>\n<span class=\"line\" data-line=\"\"><span>  v</span></span>\n<span class=\"line\" data-line=\"\"><span>requestMeta.onCacheEntryV2 callback</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  |-- if APP_PAGE ---&gt; persist html + postponedState + headers ---&gt; Platform Cache</span></span>\n<span class=\"line\" data-line=\"\"><span>  |</span></span>\n<span class=\"line\" data-line=\"\"><span>  '-- return false: continue normal Next.js response flow</span></span>\n<span class=\"line\" data-line=\"\"><span>      return true:  adapter already handled response (short-circuit)</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/invoking-entrypoints",
    "title": "Adapters: Invoking Entrypoints | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Invoking Entrypoints</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->April 30, 2026</div><p>Build output entrypoints use a <code>handler(..., ctx)</code> interface, with runtime-specific request/response types.</p>\n<h2 id=\"nodejs-runtime-runtime-nodejs\" data-docs-heading=\"\">Node.js runtime (<code>runtime: 'nodejs'</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#nodejs-runtime-runtime-nodejs\"><span></span></a></h2>\n<p>Node.js entrypoints use the following interface:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">handler</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  req: IncomingMessage</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  res: ServerResponse</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ctx: {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    waitUntil?</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> (promise</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt;) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-keyword)\"> void</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    requestMeta</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> RequestMeta</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;void&gt;</span></span></code></pre></div>\n<p>When invoking Node.js entrypoints directly, adapters can pass helpers directly on <code>requestMeta</code> instead of relying on internals. Some of the supported fields are <code>hostname</code>,\n<code>revalidate</code>, and <code>render404</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-token-function)\"> handler</span><span style=\"color:var(--shiki-color-text)\">(req</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> res</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  requestMeta</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Relative path from process.cwd() to the Next.js project directory.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    relativeProjectDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '.'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Optional hostname used by route handlers when constructing absolute URLs.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    hostname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '127.0.0.1'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Optional internal revalidate function to avoid revalidating over the network</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    revalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> ({ urlPath</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> headers</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> opts }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // platform-specific revalidate implementation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Optional function to render the 404 page for pages router `notFound: true`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    render404</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> (req</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> res</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> parsedUrl</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> setHeaders) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // platform-specific 404 rendering implementation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<p>Relevant files in the Next.js core:</p>\n<ul>\n<li><a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/app-page.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/app-page.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/app-route.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/app-route.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li>and <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/pages-api.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/pages-api.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h2 id=\"edge-runtime-runtime-edge-deprecated\" data-docs-heading=\"\">Edge runtime (<code>runtime: 'edge'</code>) (deprecated)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#edge-runtime-runtime-edge-deprecated\"><span></span></a></h2>\n<blockquote class=\"p-3 text-sm\">\n<p>The Edge Runtime is <a href=\"/docs/messages/edge-runtime-deprecated\">deprecated</a>. New routes should use the Node.js runtime.</p>\n</blockquote>\n<p>Edge entrypoints use the following interface:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">handler</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  request: Request</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ctx: {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    waitUntil?</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> (prom</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt;) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-keyword)\"> void</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    signal</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> AbortSignal</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    requestMeta</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> RequestMeta</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">Response</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span></span></code></pre></div>\n<p>The shape is aligned around <code>handler(..., ctx)</code>, but Node.js and Edge runtimes use different request/response primitives.</p>\n<p>For outputs with <code>runtime: 'edge'</code>, Next.js also provides <code>output.edgeRuntime</code> with the canonical metadata needed to invoke the entrypoint:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  modulePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  entryKey</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  handlerExport</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>After your edge runtime loads and evaluates the chunks for <code>modulePath</code>, use <code>entryKey</code> to read the registered entry from the global edge entry registry (<code>globalThis._ENTRIES</code>), then invoke <code>handlerExport</code> from that entry:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> globalThis</span><span style=\"color:var(--shiki-color-text)\">._ENTRIES[</span><span style=\"color:var(--shiki-token-constant)\">output</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">edgeRuntime</span><span style=\"color:var(--shiki-color-text)\">.entryKey]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> handler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> entry[</span><span style=\"color:var(--shiki-token-constant)\">output</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">edgeRuntime</span><span style=\"color:var(--shiki-color-text)\">.handlerExport]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-token-function)\"> handler</span><span style=\"color:var(--shiki-color-text)\">(request</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> ctx)</span></span></code></pre></div>\n<p>Use <code>edgeRuntime</code> instead of deriving registry keys or handler names from filenames.</p>\n<p>Relevant files in the Next.js core:</p>\n<ul>\n<li><a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/edge-ssr.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/edge-ssr.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/edge-app-route.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/edge-app-route.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/pages-edge-api.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/pages-edge-api.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li>and <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>packages/next/src/build/templates/middleware.ts</code><span class=\"inline-flex not-prose\"></span></a></li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/output-types",
    "title": "Adapters: Output Types | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Output Types</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 24, 2026</div><p>The <code>outputs</code> object contains arrays of build output types:</p>\n<ul>\n<li><code>outputs.pages</code>: React pages from the <code>pages/</code> directory</li>\n<li><code>outputs.pagesApi</code>: API routes from <code>pages/api/</code></li>\n<li><code>outputs.appPages</code>: React pages from the <code>app/</code> directory</li>\n<li><code>outputs.appRoutes</code>: API and metadata routes from <code>app/</code></li>\n<li><code>outputs.prerenders</code>: ISR-enabled routes and static prerenders</li>\n<li><code>outputs.staticFiles</code>: Static assets and auto-statically optimized pages</li>\n<li><code>outputs.middleware</code>: Middleware function (if present)</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Note:</strong> When <code>config.output</code> is set to <code>'export'</code>, only <code>outputs.staticFiles</code> is populated. All other arrays (<code>pages</code>, <code>appPages</code>, <code>pagesApi</code>, <code>appRoutes</code>, <code>prerenders</code>) will be empty since the entire application is exported as static files.</p>\n</blockquote>\n<p>For any route output with <code>runtime: 'edge'</code>, <code>edgeRuntime</code> is included and contains the canonical entry metadata for invoking that output in your edge runtime. Note that the Edge Runtime is <a href=\"/docs/messages/edge-runtime-deprecated\">deprecated</a>.</p>\n<h2 id=\"pages-outputspages\" data-docs-heading=\"\">Pages (<code>outputs.pages</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#pages-outputspages\"><span></span></a></h2>\n<p>React pages from the <code>pages/</code> directory:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'PAGES'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// Path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// URL pathname</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourcePage</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string   </span><span style=\"color:var(--shiki-token-comment)\">// Original source file path in pages/ directory</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  runtime</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nodejs'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'edge'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  assets</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Traced dependencies (key: relative path from repo root, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  wasmAssets</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Bundled wasm files (key: name, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  edgeRuntime</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    modulePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    entryKey: string      </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    handlerExport: string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxDuration</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Maximum duration of the route in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    preferredRegion</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-color-text)\"> string[]  </span><span style=\"color:var(--shiki-token-comment)\">// Preferred deployment region (deprecated)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    env</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Environment variables (edge runtime only)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"api-routes-outputspagesapi\" data-docs-heading=\"\">API Routes (<code>outputs.pagesApi</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#api-routes-outputspagesapi\"><span></span></a></h2>\n<p>API routes from <code>pages/api/</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'PAGES_API'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// Path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// URL pathname</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourcePage</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string   </span><span style=\"color:var(--shiki-token-comment)\">// Original relative source file path</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  runtime</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nodejs'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'edge'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  assets</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Traced dependencies (key: relative path from repo root, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  wasmAssets</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Bundled wasm files (key: name, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  edgeRuntime</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    modulePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    entryKey: string      </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    handlerExport: string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxDuration</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Maximum duration of the route in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    preferredRegion</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-color-text)\"> string[]  </span><span style=\"color:var(--shiki-token-comment)\">// Preferred deployment region (deprecated)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    env</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Environment variables (edge runtime only)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"app-pages-outputsapppages\" data-docs-heading=\"\">App Pages (<code>outputs.appPages</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#app-pages-outputsapppages\"><span></span></a></h2>\n<p>React pages from the <code>app/</code> directory:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'APP_PAGE'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// Path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// URL pathname. Includes .rsc suffix for RSC routes</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourcePage</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string   </span><span style=\"color:var(--shiki-token-comment)\">// Original relative source file path</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  runtime</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nodejs'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'edge'</span><span style=\"color:var(--shiki-token-comment)\"> // Runtime the route is built for</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  assets</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Traced dependencies (key: relative path from repo root, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  wasmAssets</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Bundled wasm files (key: name, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  edgeRuntime</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    modulePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    entryKey: string      </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    handlerExport: string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxDuration</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Maximum duration of the route in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    preferredRegion</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-color-text)\"> string[]  </span><span style=\"color:var(--shiki-token-comment)\">// Preferred deployment region (deprecated)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    env</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Environment variables (edge runtime only)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"app-routes-outputsapproutes\" data-docs-heading=\"\">App Routes (<code>outputs.appRoutes</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#app-routes-outputsapproutes\"><span></span></a></h2>\n<p>API and metadata routes from the <code>app/</code> directory:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'APP_ROUTE'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// Path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// URL pathname</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourcePage</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string   </span><span style=\"color:var(--shiki-token-comment)\">// Original relative source file path</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  runtime</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nodejs'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'edge'</span><span style=\"color:var(--shiki-token-comment)\"> // Runtime the route is built for</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  assets</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Traced dependencies (key: relative path from repo root, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  wasmAssets</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Bundled wasm files (key: name, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  edgeRuntime</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    modulePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    entryKey: string      </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    handlerExport: string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxDuration</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Maximum duration of the route in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    preferredRegion</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-color-text)\"> string[]  </span><span style=\"color:var(--shiki-token-comment)\">// Preferred deployment region (deprecated)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    env</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Environment variables (edge runtime only)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"prerenders-outputsprerenders\" data-docs-heading=\"\">Prerenders (<code>outputs.prerenders</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#prerenders-outputsprerenders\"><span></span></a></h2>\n<p>ISR-enabled routes and static prerenders:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'PRERENDER'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// URL pathname</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  parentOutputId</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string  </span><span style=\"color:var(--shiki-token-comment)\">// ID of the source page/route</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  groupId</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> number        </span><span style=\"color:var(--shiki-token-comment)\">// Revalidation group identifier (prerenders with same groupId revalidate together)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  route</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Source route matcher aligned with the filesystem route, keeping dynamic segments (e.g. /blog/[slug] for the prerendered path /blog/first)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  routeType</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'route'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'fallback'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'shell'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'page'</span><span style=\"color:var(--shiki-token-comment)\">  // Kind of canonical response</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  response</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'empty'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'initial'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'complete'</span><span style=\"color:var(--shiki-token-comment)\">  // Completeness before request-time work</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  compute</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'blocking'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'resuming'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'static'</span><span style=\"color:var(--shiki-token-comment)\">  // Request-time compute needed for the completed response</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  htmlSize</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number       </span><span style=\"color:var(--shiki-token-comment)\">// Byte size of the prerendered App Router HTML shell</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pprChain</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string&gt;  </span><span style=\"color:var(--shiki-token-comment)\">// PPR chain headers (e.g., 'next-resume': '1')</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  parentFallbackMode</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-constant)\"> null</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-color-text)\"> string  </span><span style=\"color:var(--shiki-token-comment)\">// false: no additional paths (fallback: false), null: blocking render, string: path to HTML fallback</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  fallback</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    filePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-comment)\">  // Path to the fallback file (HTML, JSON, or RSC)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    initialStatus</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Initial status code</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    initialHeaders</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string | string[]&gt;  </span><span style=\"color:var(--shiki-token-comment)\">// Initial headers</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    initialExpiration?</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Initial expiration time in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    initialRevalidate</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-comment)\">  // Initial revalidate time in seconds, or false for fully static</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    postponedState: string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-comment)\">  // Serialized PPR state used for resuming rendering</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    allowQuery</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string[]     </span><span style=\"color:var(--shiki-token-comment)\">// Allowed query parameters considered for the cache key</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    allowHeader</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string[]    </span><span style=\"color:var(--shiki-token-comment)\">// Allowed headers for ISR</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    bypassFor</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> RouteHas[]    </span><span style=\"color:var(--shiki-token-comment)\">// Cache bypass conditions</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    renderingMode</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'STATIC'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'PARTIALLY_STATIC'</span><span style=\"color:var(--shiki-token-comment)\">  // STATIC: fully static, PARTIALLY_STATIC: PPR-enabled</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    partialFallback</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> boolean  </span><span style=\"color:var(--shiki-token-comment)\">// Serves a partial fallback shell that should be upgraded to a full route in the background</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    bypassToken</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string      </span><span style=\"color:var(--shiki-token-comment)\">// Generated token that signals the prerender cache should be bypassed</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"prerender-classification\" data-docs-heading=\"\">Prerender classification<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#prerender-classification\"><span></span></a></h3>\n<p><code>routeType</code>, <code>response</code>, and <code>compute</code> are emitted together on the primary response in a prerender group. Related RSC, data, and segment outputs omit these fields. Pages Router templates with <code>fallback: false</code> also omit them because those templates are never served for unmatched URLs.</p>\n<p><code>routeType</code> identifies the kind of canonical response:</p>\n<ul>\n<li><code>route</code>: a non-UI route, such as a Route Handler</li>\n<li><code>page</code>: a page whose URL has no missing prerenderable parameters</li>\n<li><code>shell</code>: the most specific reusable page shell for its class of URLs</li>\n<li><code>fallback</code>: a reusable page response that can be specialized by filling more prerenderable parameters</li>\n</ul>\n<p><code>response</code> describes how complete the response is before request-time work:</p>\n<ul>\n<li><code>empty</code>: no initial page response can be served</li>\n<li><code>initial</code>: an initial response can be served, but it is not the completed page UI. In practice, this only applies to UI routes that are partially prerenderable</li>\n<li><code>complete</code>: the response is complete; this can include a zero-byte response body, such as a <code>204</code> Route Handler response</li>\n</ul>\n<p><code>compute</code> describes the request-time compute needed to serve the completed response:</p>\n<ul>\n<li><code>blocking</code>: no initial response can be sent before request-time compute starts; once started, the response can stream while compute continues</li>\n<li><code>resuming</code>: an initial response is served while postponed work resumes on the server</li>\n<li><code>static</code>: no server compute is required per request</li>\n</ul>\n<p><code>htmlSize</code> is only included on the primary App Router HTML output. A value of <code>0</code> means that the HTML shell is empty. Pages Router prerenders, Route Handlers, and related RSC, data, and segment outputs omit it.</p>\n<h2 id=\"static-files-outputsstaticfiles\" data-docs-heading=\"\">Static Files (<code>outputs.staticFiles</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#static-files-outputsstaticfiles\"><span></span></a></h2>\n<p>Static assets and auto-statically optimized pages:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'STATIC_FILE'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// Unique identifier for this static file output</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// Absolute filesystem path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-comment)\">// The routable URL pathname for this static file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  immutableHash</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-comment)\"> // Content hash when the filename contains a hash, indicating the file is immutable</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>See <a href=\"/docs/app/api-reference/adapters/immutable-static-assets\">Supporting immutable static assets</a> for more information about <code>immutableHash</code>.</p>\n<h2 id=\"middleware-outputsmiddleware\" data-docs-heading=\"\">Middleware (<code>outputs.middleware</code>)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#middleware-outputsmiddleware\"><span></span></a></h2>\n<p><code>middleware.ts</code> (<code>.js</code>/<code>.ts</code>) or <code>proxy.ts</code> (<code>.js</code>/<code>.ts</code>) function (if present):</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'MIDDLEWARE'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string           </span><span style=\"color:var(--shiki-token-comment)\">// Route identifier</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  filePath</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string     </span><span style=\"color:var(--shiki-token-comment)\">// Path to the built file</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathname</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string      </span><span style=\"color:var(--shiki-token-comment)\">// Always '/_middleware'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sourcePage</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Always 'middleware'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  runtime</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nodejs'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'edge'</span><span style=\"color:var(--shiki-token-comment)\"> // Runtime the route is built for</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  assets</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Traced dependencies (key: relative path from repo root, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  wasmAssets</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Bundled wasm files (key: name, value: absolute path)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  edgeRuntime</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    modulePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> string    </span><span style=\"color:var(--shiki-token-comment)\">// Absolute path to the module registered in the edge runtime</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    entryKey: string      </span><span style=\"color:var(--shiki-token-comment)\">// Canonical key used by the edge entry registry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    handlerExport: string </span><span style=\"color:var(--shiki-token-comment)\">// Export name to invoke, currently 'handler'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxDuration</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> number  </span><span style=\"color:var(--shiki-token-comment)\">// Maximum duration of the route in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    preferredRegion</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> string </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-color-text)\"> string[]  </span><span style=\"color:var(--shiki-token-comment)\">// Preferred deployment region (deprecated)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    env</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> Record</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> string</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-comment)\">  // Environment variables (edge runtime only)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    matchers</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-token-function)\"> Array</span><span style=\"color:var(--shiki-color-text)\">&lt;{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-token-comment)\">  // Source pattern</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      sourceRegex</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-token-comment)\">  // Compiled regex for matching requests</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> RouteHas</span><span style=\"color:var(--shiki-color-text)\">[] </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-comment)\">  // Positive matching conditions</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      missing</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> RouteHas</span><span style=\"color:var(--shiki-color-text)\">[] </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-comment)\">  // Negative matching conditions</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/routing-information",
    "title": "Adapters: Routing Information | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Routing Information</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 30, 2026</div><p>The <code>routing</code> object in <code>onBuildComplete</code> provides complete routing information with processed patterns ready for deployment:</p>\n<h2 id=\"routingbeforemiddleware\" data-docs-heading=\"\"><code>routing.beforeMiddleware</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingbeforemiddleware\"><span></span></a></h2>\n<p>Routes applied before middleware execution. These include generated header and redirect behavior.</p>\n<h2 id=\"routingbeforefiles\" data-docs-heading=\"\"><code>routing.beforeFiles</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingbeforefiles\"><span></span></a></h2>\n<p>Rewrite routes checked before filesystem route matching.</p>\n<h2 id=\"routingafterfiles\" data-docs-heading=\"\"><code>routing.afterFiles</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingafterfiles\"><span></span></a></h2>\n<p>Rewrite routes checked after filesystem route matching.</p>\n<h2 id=\"routingdynamicroutes\" data-docs-heading=\"\"><code>routing.dynamicRoutes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingdynamicroutes\"><span></span></a></h2>\n<p>Dynamic matchers generated from route segments such as <code>[slug]</code> and catch-all routes.</p>\n<h2 id=\"routingonmatch\" data-docs-heading=\"\"><code>routing.onMatch</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingonmatch\"><span></span></a></h2>\n<p>Routes that apply after a successful match, such as immutable cache headers for hashed static assets.</p>\n<h2 id=\"routingfallback\" data-docs-heading=\"\"><code>routing.fallback</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routingfallback\"><span></span></a></h2>\n<p>Final rewrite routes checked when earlier phases did not produce a match.</p>\n<h2 id=\"common-route-fields\" data-docs-heading=\"\">Common Route Fields<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#common-route-fields\"><span></span></a></h2>\n<p>Each route entry can include:</p>\n<ul>\n<li><code>source</code>: Original route pattern (optional for generated internal rules)</li>\n<li><code>sourceRegex</code>: Compiled regex for matching requests</li>\n<li><code>destination</code>: Internal destination or redirect destination</li>\n<li><code>headers</code>: Headers to apply</li>\n<li><code>has</code>: Positive matching conditions</li>\n<li><code>missing</code>: Negative matching conditions</li>\n<li><code>status</code>: Redirect status code</li>\n<li><code>priority</code>: Internal route priority flag</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/routing-with-next-routing",
    "title": "Adapters: Routing with @next/routing | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Routing with @next/routing</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 15, 2026</div><p>You can use <a href=\"https://www.npmjs.com/package/@next/routing\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>@next/routing</code><span class=\"inline-flex not-prose\"></span></a> to reproduce Next.js route matching behavior with data from <code>onBuildComplete</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { resolveRoutes } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@next/routing'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> pathnames</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-token-constant)\">outputs</span><span style=\"color:var(--shiki-color-text)\">.pages</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-token-constant)\">outputs</span><span style=\"color:var(--shiki-color-text)\">.pagesApi</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-token-constant)\">outputs</span><span style=\"color:var(--shiki-color-text)\">.appPages</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-token-constant)\">outputs</span><span style=\"color:var(--shiki-color-text)\">.appRoutes</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-token-constant)\">outputs</span><span style=\"color:var(--shiki-color-text)\">.staticFiles</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((output) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> output</span><span style=\"color:var(--shiki-color-text)\">.pathname)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> result</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> resolveRoutes</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  url</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(requestUrl)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  buildId</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-color-text)\">.basePath </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  i18n</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-color-text)\">.i18n</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> Headers</span><span style=\"color:var(--shiki-color-text)\">(requestHeaders)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  requestBody</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // ReadableStream</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pathnames</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  routes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> routing</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  invokeMiddleware</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> (ctx) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // platform-specific middleware invocation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">result</span><span style=\"color:var(--shiki-color-text)\">.resolvedPathname) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Resolved pathname:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> result</span><span style=\"color:var(--shiki-color-text)\">.resolvedPathname)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Resolved query:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> result</span><span style=\"color:var(--shiki-color-text)\">.resolvedQuery)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Invocation target:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> result</span><span style=\"color:var(--shiki-color-text)\">.invocationTarget)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>resolveRoutes()</code> returns:</p>\n<ul>\n<li><code>middlewareResponded</code>: <code>true</code> when middleware already sent a response (the adapter should not invoke an entrypoint).</li>\n<li><code>externalRewrite</code>: A <code>URL</code> when routing resolved to an external rewrite destination.</li>\n<li><code>redirect</code>: An object with <code>url</code> (<code>URL</code>) and <code>status</code> when the request should be redirected.</li>\n<li><code>resolvedPathname</code>: The route pathname selected by Next.js routing. For dynamic routes, this is the matched route template such as <code>/blog/[slug]</code>.</li>\n<li><code>resolvedQuery</code>: The final query after rewrites or middleware have added or replaced search params.</li>\n<li><code>invocationTarget</code>: The concrete pathname and query to invoke for the matched route.</li>\n<li><code>resolvedHeaders</code>: A <code>Headers</code> object containing any headers added or modified during routing.</li>\n<li><code>status</code>: An HTTP status code set by routing (for example from a redirect or rewrite rule).</li>\n<li><code>routeMatches</code>: A record of named matches extracted from dynamic route segments.</li>\n</ul>\n<p>For example, if <code>/blog/post-1?draft=1</code> matches <code>/blog/[slug]?slug=post-1</code>, <code>resolvedPathname</code> is <code>/blog/[slug]</code> while <code>invocationTarget.pathname</code> is <code>/blog/post-1</code>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/runtime-integration",
    "title": "Adapters: Runtime Integration | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Runtime Integration</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 29, 2026</div><p>The Deployment Adapter API is a <strong>build-time</strong> interface. It tells your platform what was built and how to route requests. <strong>Runtime</strong> behavior (request handling, streaming, caching) is handled by the Next.js server itself and by the cache interfaces <a href=\"/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath\"><code>cacheHandler</code></a> and <a href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><code>cacheHandlers</code></a>.</p>\n<p>Together, the adapter and cache interfaces form the complete platform integration surface:</p>\n<ul>\n<li><strong>Adapter</strong> (build-time): processes build outputs, configures routing, and sets up platform-specific infrastructure.</li>\n<li><strong>Cache Interfaces</strong> (runtime): <code>cacheHandler</code> manages ISR/server cache storage and revalidation across instances; <code>cacheHandlers</code> configures <code>'use cache'</code> directive backends and tag coordination.</li>\n</ul>\n<h2 id=\"handler-context\" data-docs-heading=\"\">Handler Context<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#handler-context\"><span></span></a></h2>\n<p>When invoking entrypoints, adapters pass a <code>ctx</code> object to the Next.js handler. Key fields include:</p>\n<ul>\n<li><strong><code>ctx.waitUntil</code></strong>: a function that accepts a promise. Use this to keep the serverless function alive after the response is sent, allowing background work like cache revalidation to complete.</li>\n<li><strong><code>requestMeta.onCacheEntryV2</code></strong> (set via <code>addRequestMeta</code>): a callback that fires when a cache entry is generated or looked up. Use this to observe all cache operations (not just PPR) and propagate cache updates to your platform's storage backend. This callback fires on the instance that handled the request. For multi-instance deployments, your adapter should propagate updates to shared storage. See <a href=\"/docs/app/guides/how-revalidation-works\">How Revalidation Works</a> for coordination patterns.</li>\n</ul>\n<h2 id=\"ppr-chain-headers\" data-docs-heading=\"\">PPR Chain Headers<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#ppr-chain-headers\"><span></span></a></h2><p>In the <a href=\"/docs/app/api-reference/adapters/output-types#prerenders-outputsprerenders\">prerenders output type</a>, <code>pprChain.headers</code> contains the headers needed for the <a href=\"/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter\">resume protocol</a>. Specifically, it contains <code>{ 'next-resume': '1' }</code>.</p><p>When your adapter detects a PPR-enabled route with a cached static shell:</p><ol>\n<li>Set the <code>pprChain.headers</code> on the internal request to the Next.js handler.</li>\n<li>Send the request as a <strong>POST</strong> with the <code>postponedState</code> as the request body.</li>\n<li>The handler will render only the deferred Suspense boundaries and stream the result.</li>\n</ol><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> In standard <code>next start</code>, the server handles both the shell and dynamic render in a single pass automatically. The resume protocol is useful for adapter-based deployments and CDN-to-origin architectures that want to serve the shell separately. See the <a href=\"/docs/app/guides/ppr-platform-guide\">PPR Platform Guide</a> for the full implementation context.</p>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/testing-adapters",
    "title": "Adapters: Testing Adapters | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Testing Adapters</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 7, 2026</div><p>Next.js provides a test harness for validating adapters. Running the end-to-end tests for deployment.</p>\n<p>Example GitHub Actions workflow:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">.github/workflows/test-e2e-deploy.yml</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> test-e2e-deploy</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">on</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  workflow_dispatch</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    inputs</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      nextjsRef</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        description</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Next.js repo ref (branch/tag/SHA)'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        default</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'canary'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  # schedule:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  #   - cron: '0 2 * * *'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">jobs</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  build</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Build Next.js + adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    runs-on</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ubuntu-latest</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    timeout-minutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 30</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    steps</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/checkout@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> adapter</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/checkout@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          repository</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> vercel/next.js</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          ref</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ${{ inputs.nextjsRef || 'canary' }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          fetch-depth</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 25</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/setup-node@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-keyword)\">node-version</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '20'</span><span style=\"color:var(--shiki-color-text)\"> }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Setup pnpm</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> npm i -g corepack@0.31 &amp;&amp; corepack enable</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Install &amp; build Next.js</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        working-directory</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> pnpm install &amp;&amp; pnpm build &amp;&amp; pnpm install</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Install Playwright</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        working-directory</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> pnpm playwright install --with-deps chromium</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Build adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        working-directory</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> pnpm install &amp;&amp; pnpm build</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/cache/save@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> |</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            ~/.cache/ms-playwright</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> build-${{ github.sha }}-${{ github.run_id }}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  test</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Tests (${{ matrix.group }})</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    needs</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> build</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    runs-on</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ubuntu-latest</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    timeout-minutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 60</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    strategy</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      fail-fast</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      matrix</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        group</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            1/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            2/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            3/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            4/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            5/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            6/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            7/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            8/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            9/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            10/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            11/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            12/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            13/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            14/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            15/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            16/16</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    steps</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/cache/restore@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> |</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string)\">            ~/.cache/ms-playwright</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> build-${{ github.sha }}-${{ github.run_id }}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">uses</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> actions/setup-node@v4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        with</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-keyword)\">node-version</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '20'</span><span style=\"color:var(--shiki-color-text)\"> }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Setup pnpm</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> npm i -g corepack@0.31 &amp;&amp; corepack enable</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Ensure Playwright browser</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        working-directory</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> pnpm playwright install chromium</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Make scripts executable</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> chmod +x adapter/scripts/e2e-deploy.sh</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">          adapter/scripts/e2e-logs.sh</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">          adapter/scripts/e2e-cleanup.sh</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      - </span><span style=\"color:var(--shiki-token-keyword)\">name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> Run deploy tests</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        working-directory</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> nextjs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        env</span><span style=\"color:var(--shiki-token-keyword)\">:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TEST_MODE</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> deploy</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_E2E_TEST_TIMEOUT</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 240000</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_EXTERNAL_TESTS_FILTERS</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> test/deploy-tests-manifest.json</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          ADAPTER_DIR</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ${{ github.workspace }}/adapter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          IS_TURBOPACK_TEST</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TEST_JOB</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TELEMETRY_DISABLED</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">          # Change these to your adapter's scripts</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">          # Keep as-is if the scripts are in the adapter repository `scripts` directory</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TEST_DEPLOY_SCRIPT_PATH</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ${{ github.workspace }}/adapter/scripts/e2e-deploy.sh</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TEST_DEPLOY_LOGS_SCRIPT_PATH</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ${{ github.workspace }}/adapter/scripts/e2e-logs.sh</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          NEXT_TEST_CLEANUP_SCRIPT_PATH</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ${{ github.workspace }}/adapter/scripts/e2e-cleanup.sh</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        run</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> node run-tests.js --timings -g ${{ matrix.group }} -c 2 --type e2e</span></span></code></pre></div>\n<p>The test harness looks for these environment variables:</p>\n<ul>\n<li><code>NEXT_TEST_DEPLOY_SCRIPT_PATH</code>: Path to the executable that builds and deploys the isolated test app</li>\n<li><code>NEXT_TEST_DEPLOY_LOGS_SCRIPT_PATH</code>: Path to the executable that returns build and runtime logs for that deployment</li>\n<li><code>NEXT_TEST_CLEANUP_SCRIPT_PATH</code>: Path to the optional executable that tears the deployment down after the test run</li>\n</ul>\n<h2 id=\"custom-deploy-script-contract\" data-docs-heading=\"\">Custom deploy script contract<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#custom-deploy-script-contract\"><span></span></a></h2>\n<p>The deploy script <code>NEXT_TEST_DEPLOY_SCRIPT_PATH</code> is executed with <code>cwd</code> set to the isolated temporary app created by the Next.js test harness.</p>\n<p>The deploy script must follow this contract:</p>\n<ul>\n<li>Exit with a non-zero code on failure.</li>\n<li>Print the deployment URL to <code>stdout</code>. This will be used to verify the deployment. Avoid writing anything else to <code>stdout</code>.</li>\n<li>Write diagnostic output to <code>stderr</code> or to files inside the working directory.</li>\n</ul>\n<p>Because the deploy script and logs script run as separate processes, any data you want to use later, such as build IDs or server logs, should be persisted to files inside the working directory.</p>\n<p>Example deploy script:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">scripts/e2e-deploy.sh</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">#!/usr/bin/env bash</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">set</span><span style=\"color:var(--shiki-token-string)\"> -euo</span><span style=\"color:var(--shiki-token-string)\"> pipefail</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Install the adapter, build the app, and deploy or start it.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">node</span><span style=\"color:var(--shiki-token-string)\"> -e</span><span style=\"color:var(--shiki-token-string-expression)\"> \"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">const pkg=JSON.parse(require('fs').readFileSync('package.json','utf8'));</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">pkg.dependencies=pkg.dependencies||{};</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">pkg.dependencies['adapter']='file:${ADAPTER_DIR}';</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">require('fs').writeFileSync('package.json',JSON.stringify(pkg,null,2));</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">\"</span><span style=\"color:var(--shiki-token-keyword)\"> &gt;&amp;2</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Set the adapter path so that the app uses it.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-color-text)\"> NEXT_ADAPTER_PATH</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"${ADAPTER_DIR}/dist/index.js\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Build the app</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> build</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Write any metadata needed later to files in the working directory.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">BUILD_ID</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"$(</span><span style=\"color:var(--shiki-token-function)\">cat</span><span style=\"color:var(--shiki-token-string)\"> .next/BUILD_ID</span><span style=\"color:var(--shiki-token-string-expression)\">)\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">DEPLOYMENT_ID</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"my-adapter-local\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># If your adapter enables immutable static assets, set this to \"1\".</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NEXT_SUPPORTS_IMMUTABLE_ASSETS</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"0\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  echo</span><span style=\"color:var(--shiki-token-string-expression)\"> \"BUILD_ID: $BUILD_ID\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  echo</span><span style=\"color:var(--shiki-token-string-expression)\"> \"DEPLOYMENT_ID: $DEPLOYMENT_ID\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  echo</span><span style=\"color:var(--shiki-token-string-expression)\"> \"NEXT_SUPPORTS_IMMUTABLE_ASSETS: $NEXT_SUPPORTS_IMMUTABLE_ASSETS\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">&gt;&gt;</span><span style=\"color:var(--shiki-color-text)\"> .adapter-build.log</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Start or deploy the app. Capture the URL at this point or make the script output the URL to stdout.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">provider-cli-to-deploy</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Example URL output:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># echo \"http://127.0.0.1:3000\"</span></span></code></pre></div>\n<h2 id=\"custom-logs-script-contract\" data-docs-heading=\"\">Custom logs script contract<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#custom-logs-script-contract\"><span></span></a></h2>\n<p>The logs script <code>NEXT_TEST_DEPLOY_LOGS_SCRIPT_PATH</code> is executed with <code>cwd</code> set to the isolated temporary app created by the Next.js test harness.</p>\n<p>Additionally it receives <code>NEXT_TEST_DIR</code> and <code>NEXT_TEST_DEPLOY_URL</code> as environment variables.</p>\n<p>Its output must include lines starting with:</p>\n<ul>\n<li><code>BUILD_ID:</code></li>\n<li><code>DEPLOYMENT_ID:</code></li>\n<li><code>NEXT_SUPPORTS_IMMUTABLE_ASSETS:</code></li>\n</ul>\n<p>After those markers, the logs script can print any additional build or server logs that would help debug failures.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">scripts/e2e-logs.sh</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">#!/usr/bin/env bash</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">set</span><span style=\"color:var(--shiki-token-string)\"> -euo</span><span style=\"color:var(--shiki-token-string)\"> pipefail</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">if</span><span style=\"color:var(--shiki-color-text)\"> [ </span><span style=\"color:var(--shiki-token-keyword)\">-f</span><span style=\"color:var(--shiki-token-string-expression)\"> \".adapter-build.log\"</span><span style=\"color:var(--shiki-color-text)\"> ]; </span><span style=\"color:var(--shiki-token-keyword)\">then</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cat</span><span style=\"color:var(--shiki-token-string-expression)\"> \".adapter-build.log\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">fi</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">if</span><span style=\"color:var(--shiki-color-text)\"> [ </span><span style=\"color:var(--shiki-token-keyword)\">-f</span><span style=\"color:var(--shiki-token-string-expression)\"> \".adapter-server.log\"</span><span style=\"color:var(--shiki-color-text)\"> ]; </span><span style=\"color:var(--shiki-token-keyword)\">then</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  echo</span><span style=\"color:var(--shiki-token-string-expression)\"> \"=== .adapter-server.log ===\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cat</span><span style=\"color:var(--shiki-token-string-expression)\"> \".adapter-server.log\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">fi</span></span></code></pre></div>\n<p>One pattern is to have the deploy script write <code>.adapter-build.log</code> and <code>.adapter-server.log</code>, then have the logs script replay those files so the harness can extract the required markers. This is one option, each platform has different ways to get the logs.</p>\n<h2 id=\"custom-cleanup-script-contract\" data-docs-heading=\"\">Custom cleanup script contract<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#custom-cleanup-script-contract\"><span></span></a></h2>\n<p>The cleanup script <code>NEXT_TEST_CLEANUP_SCRIPT_PATH</code> is executed with <code>cwd</code> set to the isolated temporary app created by the Next.js test harness.</p>\n<p>Additionally it receives <code>NEXT_TEST_DIR</code> and <code>NEXT_TEST_DEPLOY_URL</code> as environment variables.</p>\n<p>The cleanup script can be used to clean up any resources created by the deploy script. It runs after the tests have completed.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/adapters/use-cases",
    "title": "Adapters: Use Cases | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Use Cases</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 30, 2026</div><p>Common use cases for adapters include:</p>\n<ul>\n<li><strong>Deployment Platform Integration</strong>: Automatically configure build outputs for specific hosting platforms</li>\n<li><strong>Asset Processing</strong>: Transform or optimize build outputs</li>\n<li><strong>Monitoring Integration</strong>: Collect build metrics and route information</li>\n<li><strong>Custom Bundling</strong>: Package outputs in platform-specific formats</li>\n<li><strong>Build Validation</strong>: Ensure outputs meet specific requirements</li>\n<li><strong>Route Generation</strong>: Use processed route information to generate platform-specific routing configs</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/cli",
    "title": "API Reference: CLI | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">CLI</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Next.js comes with <strong>two</strong> Command Line Interface (CLI) tools:</p>\n<ul>\n<li><strong><code>create-next-app</code></strong>: Quickly create a new Next.js application using the default template or an <a href=\"https://github.com/vercel/next.js/tree/canary/examples\" rel=\"noopener noreferrer\" target=\"_blank\">example<span class=\"inline-flex not-prose\"></span></a> from a public GitHub repository.</li>\n<li><strong><code>next</code></strong>: Run the Next.js development server, build your application, and more.</li>\n</ul></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/cli/create-next-app\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">create-next-app</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Create Next.js apps using one command with the create-next-app CLI.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/cli/next\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">next CLI</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to run and build your application with the Next.js CLI.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/cli/create-next-app",
    "title": "CLI: create-next-app | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">create-next-app</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 10, 2026</div>\n<p>The <code>create-next-app</code> CLI allow you to create a new Next.js application using the default template or an <a href=\"https://github.com/vercel/next.js/tree/canary/examples\" rel=\"noopener noreferrer\" target=\"_blank\">example<span class=\"inline-flex not-prose\"></span></a> from a public GitHub repository. It is the easiest way to get started with Next.js.</p>\n<p>Basic usage:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_kgqotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_kgqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_14gqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_14gqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_1kgqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_1kgqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_24gqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_24gqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> create</span><span style=\"color:var(--shiki-token-string)\"> next-app</span><span style=\"color:var(--shiki-color-text)\"> [project-name] [options]</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The following options are available:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Options</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h</code> or <code>--help</code></td><td>Show all available options</td></tr><tr><td><code>-v</code> or <code>--version</code></td><td>Output the version number</td></tr><tr><td><code>--no-*</code></td><td>Negate default options. E.g. <code>--no-ts</code></td></tr><tr><td><code>--ts</code> or <code>--typescript</code></td><td>Initialize as a TypeScript project (default)</td></tr><tr><td><code>--js</code> or <code>--javascript</code></td><td>Initialize as a JavaScript project</td></tr><tr><td><code>--tailwind</code></td><td>Initialize with Tailwind CSS config (default)</td></tr><tr><td><code>--react-compiler</code></td><td>Initialize with React Compiler enabled</td></tr><tr><td><code>--eslint</code></td><td>Initialize with ESLint config</td></tr><tr><td><code>--biome</code></td><td>Initialize with Biome config</td></tr><tr><td><code>--no-linter</code></td><td>Skip linter configuration</td></tr><tr><td><code>--app</code></td><td>Initialize as an App Router project</td></tr><tr><td><code>--api</code></td><td>Initialize a project with only route handlers</td></tr><tr><td><code>--src-dir</code></td><td>Initialize inside a <code>src/</code> directory</td></tr><tr><td><code>--turbopack</code></td><td>Force enable Turbopack in generated package.json (enabled by default)</td></tr><tr><td><code>--webpack</code></td><td>Force enable Webpack in generated package.json</td></tr><tr><td><code>--import-alias &lt;alias-to-configure&gt;</code></td><td>Specify import alias to use (default \"@/*\")</td></tr><tr><td><code>--empty</code></td><td>Initialize an empty project</td></tr><tr><td><code>--use-npm</code></td><td>Explicitly tell the CLI to bootstrap the application using npm</td></tr><tr><td><code>--use-pnpm</code></td><td>Explicitly tell the CLI to bootstrap the application using pnpm</td></tr><tr><td><code>--use-yarn</code></td><td>Explicitly tell the CLI to bootstrap the application using Yarn</td></tr><tr><td><code>--use-bun</code></td><td>Explicitly tell the CLI to bootstrap the application using Bun</td></tr><tr><td><code>-e</code> or <code>--example [name] [github-url]</code></td><td>An example to bootstrap the app with</td></tr><tr><td><code>--example-path &lt;path-to-example&gt;</code></td><td>Specify the path to the example separately</td></tr><tr><td><code>--reset-preferences</code></td><td>Explicitly tell the CLI to reset any stored preferences</td></tr><tr><td><code>--skip-install</code></td><td>Explicitly tell the CLI to skip installing packages</td></tr><tr><td><code>--disable-git</code></td><td>Explicitly tell the CLI to disable git initialization</td></tr><tr><td><code>--agents-md</code></td><td>Include <code>AGENTS.md</code> and <code>CLAUDE.md</code> to guide coding agents (default)</td></tr><tr><td><code>--yes</code></td><td>Use previous preferences or defaults for all options</td></tr></tbody></table></div>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"with-the-default-template\" data-docs-heading=\"\">With the default template<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-the-default-template\"><span></span></a></h3>\n<p>To create a new app using the default template, run the following command in your terminal:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_kjaotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_kjaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_14jaotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_14jaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_1kjaotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_1kjaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_24jaotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_24jaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> create</span><span style=\"color:var(--shiki-token-string)\"> next-app</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>On installation, you'll see the following prompts:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>What is your project named? my-app</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to use the recommended Next.js defaults?</span></span>\n<span class=\"line\" data-line=\"\"><span>    Yes, use recommended defaults - TypeScript, ESLint, Tailwind CSS, App Router, AGENTS.md</span></span>\n<span class=\"line\" data-line=\"\"><span>    No, reuse previous settings</span></span>\n<span class=\"line\" data-line=\"\"><span>    No, customize settings - Choose your own preferences</span></span></code></pre></div>\n<p>If you choose to <code>customize settings</code>, you'll see the following prompts:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>Would you like to use TypeScript? No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>Which linter would you like to use? ESLint / Biome / None</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to use React Compiler? No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to use Tailwind CSS? No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like your code inside a `src/` directory? No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to use App Router? (recommended) No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to customize the import alias (`@/*` by default)? No / Yes</span></span>\n<span class=\"line\" data-line=\"\"><span>What import alias would you like configured? @/*</span></span>\n<span class=\"line\" data-line=\"\"><span>Would you like to include AGENTS.md to guide coding agents to write up-to-date Next.js code? No / Yes</span></span></code></pre></div>\n<p>After the prompts, <code>create-next-app</code> will create a folder with your project name and install the required dependencies.</p>\n<h3 id=\"linter-options\" data-docs-heading=\"\">Linter Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#linter-options\"><span></span></a></h3>\n<p><strong>ESLint</strong>: The traditional and most popular JavaScript linter. Includes Next.js-specific rules from <code>@next/eslint-plugin-next</code>.</p>\n<p><strong>Biome</strong>: A fast, modern linter and formatter that combines the functionality of ESLint and Prettier. Includes built-in Next.js and React domain support for optimal performance.</p>\n<p><strong>None</strong>: Skip linter configuration entirely. You can always add a linter later.</p>\n<p>Once you've answered the prompts, a new project will be created with your chosen configuration.</p>\n<h3 id=\"with-an-official-nextjs-example\" data-docs-heading=\"\">With an official Next.js example<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-an-official-nextjs-example\"><span></span></a></h3>\n<p>To create a new app using an official Next.js example, use the <code>--example</code> flag. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_knaotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_knaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_14naotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_14naotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_1knaotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_1knaotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_24naotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_24naotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> create</span><span style=\"color:var(--shiki-token-string)\"> next-app</span><span style=\"color:var(--shiki-token-string)\"> --example</span><span style=\"color:var(--shiki-color-text)\"> [example-name] [your-project-name]</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>You can view a list of all available examples along with setup instructions in the <a href=\"https://github.com/vercel/next.js/tree/canary/examples\" rel=\"noopener noreferrer\" target=\"_blank\">Next.js repository<span class=\"inline-flex not-prose\"></span></a>.</p>\n<h3 id=\"with-any-public-github-example\" data-docs-heading=\"\">With any public GitHub example<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-any-public-github-example\"><span></span></a></h3>\n<p>To create a new app using any public GitHub example, use the <code>--example</code> option with the GitHub repository's URL. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_kp2otbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_kp2otbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_14p2otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_14p2otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_1kp2otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_1kp2otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_24p2otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_24p2otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> create</span><span style=\"color:var(--shiki-token-string)\"> next-app</span><span style=\"color:var(--shiki-token-string)\"> --example</span><span style=\"color:var(--shiki-token-string-expression)\"> \"https://github.com/.../\"</span><span style=\"color:var(--shiki-color-text)\"> [your-project-name]</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n</div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/cli/next",
    "title": "CLI: next CLI | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">next CLI</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 5, 2026</div>\n<p>The Next.js CLI allows you to develop, build, start your application, and more.</p>\n<p>Basic usage:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_19qotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_19qotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_29qotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_29qotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_39qotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_39qotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_49qotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_49qotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> next</span><span style=\"color:var(--shiki-color-text)\"> [command] [options]</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: With <code>npm run</code>, use <code>--</code> before CLI flags so npm forwards them to <code>next</code>. This is not required for <code>pnpm</code>, <code>yarn</code>, or <code>bun</code>.</p>\n</blockquote>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The following options are available:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Options</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h</code> or <code>--help</code></td><td>Shows all available options</td></tr><tr><td><code>-v</code> or <code>--version</code></td><td>Outputs the Next.js version number</td></tr></tbody></table></div>\n<h3 id=\"commands\" data-docs-heading=\"\">Commands<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#commands\"><span></span></a></h3>\n<p>The following commands are available:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Command</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><a href=\"#next-dev-options\"><code>dev</code></a></td><td>Starts Next.js in development mode with Hot Module Reloading, error reporting, and more.</td></tr><tr><td><a href=\"#next-build-options\"><code>build</code></a></td><td>Creates an optimized production build of your application. Displaying information about each route.</td></tr><tr><td><a href=\"#next-start-options\"><code>start</code></a></td><td>Starts Next.js in production mode. The application should be compiled with <code>next build</code> first.</td></tr><tr><td><a href=\"#next-info-options\"><code>info</code></a></td><td>Prints relevant details about the current system which can be used to report Next.js bugs.</td></tr><tr><td><a href=\"#next-telemetry-options\"><code>telemetry</code></a></td><td>Allows you to enable or disable Next.js' completely anonymous telemetry collection.</td></tr><tr><td><a href=\"#next-typegen-options\"><code>typegen</code></a></td><td>Generates TypeScript definitions for routes, pages, layouts, and route handlers without running a full build.</td></tr><tr><td><a href=\"#next-upgrade-options\"><code>upgrade</code></a></td><td>Upgrades your Next.js application to the latest version.</td></tr><tr><td><a href=\"#next-experimental-analyze-options\"><code>experimental-analyze</code></a></td><td>Analyzes bundle output using Turbopack. Does not produce build artifacts.</td></tr></tbody></table></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Running <code>next</code> without a command is an alias for <code>next dev</code>.</p>\n</blockquote>\n<h3 id=\"next-dev-options\" data-docs-heading=\"\"><code>next dev</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-dev-options\"><span></span></a></h3>\n<p><code>next dev</code> starts the application in development mode with Hot Module Reloading (HMR), error reporting, and more.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Development builds output to <code>.next/dev</code> instead of <code>.next</code>. This allows you to run <code>next dev</code> and <code>next build</code> concurrently without conflicts.</p>\n</blockquote>\n<p>The following options are available when running <code>next dev</code>:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory in which to build the application. If not provided, current directory is used.</td></tr><tr><td><code>--turbopack</code></td><td>Force enable <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a> (enabled by default). Also available as <code>--turbo</code>.</td></tr><tr><td><code>--webpack</code></td><td>Use Webpack instead of the default <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a> bundler for development.</td></tr><tr><td><code>-p</code> or <code>--port &lt;port&gt;</code></td><td>Specify a port number on which to start the application. Default: 3000, env: PORT</td></tr><tr><td><code>-H</code>or <code>--hostname &lt;hostname&gt;</code></td><td>Specify a hostname on which to start the application. Useful for making the application available for other devices on the network. Default: 0.0.0.0</td></tr><tr><td><code>--experimental-https</code></td><td>Starts the server with HTTPS and generates a self-signed certificate.</td></tr><tr><td><code>--experimental-https-key &lt;path&gt;</code></td><td>Path to a HTTPS key file.</td></tr><tr><td><code>--experimental-https-cert &lt;path&gt;</code></td><td>Path to a HTTPS certificate file.</td></tr><tr><td><code>--experimental-https-ca &lt;path&gt;</code></td><td>Path to a HTTPS certificate authority file.</td></tr><tr><td><code>--experimental-upload-trace &lt;traceUrl&gt;</code></td><td>Reports a subset of the debugging trace to a remote HTTP URL.</td></tr><tr><td><code>--experimental-cpu-prof</code></td><td>Enables CPU profiling using V8's inspector. Profiles are saved to <code>.next-profiles/</code> on exit.</td></tr></tbody></table></div>\n<h3 id=\"next-build-options\" data-docs-heading=\"\"><code>next build</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-build-options\"><span></span></a></h3>\n<p><code>next build</code> creates an optimized production build of your application. The output displays information about each route. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\"> (app)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">┌</span><span style=\"color:var(--shiki-token-string)\"> ○</span><span style=\"color:var(--shiki-token-string)\"> /_not-found</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">└</span><span style=\"color:var(--shiki-token-string)\"> ƒ</span><span style=\"color:var(--shiki-token-string)\"> /products/[id]</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">○</span><span style=\"color:var(--shiki-color-text)\">  (Static)   prerendered as static content</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">ƒ</span><span style=\"color:var(--shiki-color-text)\">  (Dynamic)  server-rendered on demand</span></span></code></pre></div>\n<p>See the <a href=\"/docs/app/guides/building\">Building guide</a> to learn how to read the output, prerender dynamic routes, and debug build errors.</p>\n<p>The following options are available for the <code>next build</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory on which to build the application. If not provided, the current directory will be used.</td></tr><tr><td><code>--turbopack</code></td><td>Force enable <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a> (enabled by default). Also available as <code>--turbo</code>.</td></tr><tr><td><code>--webpack</code></td><td>Build using Webpack.</td></tr><tr><td><code>-d</code> or <code>--debug</code></td><td>Enables a more verbose build output. With this flag enabled additional build output like rewrites, redirects, and headers will be shown.</td></tr><tr><td></td><td></td></tr><tr><td><code>--profile</code></td><td>Enables production <a href=\"https://react.dev/reference/react/Profiler\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">profiling for React<span class=\"inline-flex not-prose\"></span></a>.</td></tr><tr><td><code>--no-lint</code></td><td>Disables linting. <em>Note: linting will be removed from <code>next build</code> in Next 16. If you're using Next 15.5+ with a linter other than <code>eslint</code>, linting during build will not occur.</em></td></tr><tr><td><code>--no-mangling</code></td><td>Disables <a href=\"https://en.wikipedia.org/wiki/Name_mangling\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">mangling<span class=\"inline-flex not-prose\"></span></a>. This may affect performance and should only be used for debugging purposes.</td></tr><tr><td><code>--experimental-app-only</code></td><td>Builds only App Router routes.</td></tr><tr><td><code>--experimental-build-mode [mode]</code></td><td>Uses an experimental build mode. (choices: \"compile\", \"generate\", default: \"default\")</td></tr><tr><td><code>--debug-prerender</code></td><td>Debug prerender errors in development.</td></tr><tr><td><code>--debug-build-paths=&lt;patterns&gt;</code></td><td>Build only specific routes for debugging.</td></tr><tr><td><code>--experimental-cpu-prof</code></td><td>Enables CPU profiling using V8's inspector. Profiles are saved to <code>.next-profiles/</code> on exit.</td></tr></tbody></table></div>\n<h3 id=\"next-start-options\" data-docs-heading=\"\"><code>next start</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-start-options\"><span></span></a></h3>\n<p><code>next start</code> starts the application in production mode. The application should be compiled with <a href=\"#next-build-options\"><code>next build</code></a> first.</p>\n<p>The following options are available for the <code>next start</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h</code> or <code>--help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory on which to start the application. If no directory is provided, the current directory will be used.</td></tr><tr><td><code>-p</code> or <code>--port &lt;port&gt;</code></td><td>Specify a port number on which to start the application. (default: 3000, env: PORT)</td></tr><tr><td><code>-H</code> or <code>--hostname &lt;hostname&gt;</code></td><td>Specify a hostname on which to start the application (default: 0.0.0.0).</td></tr><tr><td><code>--keepAliveTimeout &lt;keepAliveTimeout&gt;</code></td><td>Specify the maximum amount of milliseconds to wait before closing the inactive connections.</td></tr><tr><td><code>--experimental-cpu-prof</code></td><td>Enables CPU profiling using V8's inspector. Profiles are saved to <code>.next-profiles/</code> on exit.</td></tr></tbody></table></div>\n<h3 id=\"next-info-options\" data-docs-heading=\"\"><code>next info</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-info-options\"><span></span></a></h3>\n<p><code>next info</code> prints relevant details about the current system which can be used to report Next.js bugs when opening a <a href=\"https://github.com/vercel/next.js/issues\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub issue<span class=\"inline-flex not-prose\"></span></a>. This information includes Operating System platform/arch/version, Binaries (Node.js, npm, Yarn, pnpm), package versions (<code>next</code>, <code>react</code>, <code>react-dom</code>), and more.</p>\n<p>The output should look like this:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Operating</span><span style=\"color:var(--shiki-token-string)\"> System:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Platform:</span><span style=\"color:var(--shiki-token-string)\"> darwin</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Arch:</span><span style=\"color:var(--shiki-token-string)\"> arm64</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Version:</span><span style=\"color:var(--shiki-token-string)\"> Darwin</span><span style=\"color:var(--shiki-token-string)\"> Kernel</span><span style=\"color:var(--shiki-token-string)\"> Version</span><span style=\"color:var(--shiki-token-constant)\"> 23.6.0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Available</span><span style=\"color:var(--shiki-token-string)\"> memory</span><span style=\"color:var(--shiki-color-text)\"> (MB): 65536</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Available</span><span style=\"color:var(--shiki-token-string)\"> CPU</span><span style=\"color:var(--shiki-token-string)\"> cores:</span><span style=\"color:var(--shiki-token-constant)\"> 10</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Binaries:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Node:</span><span style=\"color:var(--shiki-token-constant)\"> 20.12.0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  npm:</span><span style=\"color:var(--shiki-token-constant)\"> 10.5.0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  Yarn:</span><span style=\"color:var(--shiki-token-constant)\"> 1.22.19</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  pnpm:</span><span style=\"color:var(--shiki-token-constant)\"> 9.6.0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Relevant</span><span style=\"color:var(--shiki-token-string)\"> Packages:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  next:</span><span style=\"color:var(--shiki-token-string)\"> 15.0.0-canary.115</span><span style=\"color:var(--shiki-token-string)\"> //</span><span style=\"color:var(--shiki-token-string)\"> Latest</span><span style=\"color:var(--shiki-token-string)\"> available</span><span style=\"color:var(--shiki-token-string)\"> version</span><span style=\"color:var(--shiki-token-string)\"> is</span><span style=\"color:var(--shiki-token-string)\"> detected</span><span style=\"color:var(--shiki-color-text)\"> (15.0.0-canary.115).</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  eslint-config-next:</span><span style=\"color:var(--shiki-token-constant)\"> 14.2.5</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  react:</span><span style=\"color:var(--shiki-token-string)\"> 19.0.0-rc</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  react-dom:</span><span style=\"color:var(--shiki-token-constant)\"> 19.0.0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  typescript:</span><span style=\"color:var(--shiki-token-constant)\"> 5.5.4</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Next.js</span><span style=\"color:var(--shiki-token-string)\"> Config:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  output:</span><span style=\"color:var(--shiki-token-string)\"> N/A</span></span></code></pre></div>\n<p>The following options are available for the <code>next info</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h</code> or <code>--help</code></td><td>Show all available options</td></tr><tr><td><code>--verbose</code></td><td>Collects additional information for debugging.</td></tr></tbody></table></div>\n<h3 id=\"next-telemetry-options\" data-docs-heading=\"\"><code>next telemetry</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-telemetry-options\"><span></span></a></h3>\n<p>Next.js collects <strong>completely anonymous</strong> telemetry data about general usage. Participation in this anonymous program is optional, and you can opt-out if you prefer not to share information.</p>\n<p>The following options are available for the <code>next telemetry</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>--enable</code></td><td>Enables Next.js' telemetry collection.</td></tr><tr><td><code>--disable</code></td><td>Disables Next.js' telemetry collection.</td></tr></tbody></table></div>\n<p>Learn more about <a href=\"/telemetry\">Telemetry</a>.</p>\n<h3 id=\"next-typegen-options\" data-docs-heading=\"\"><code>next typegen</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-typegen-options\"><span></span></a></h3>\n<p><code>next typegen</code> generates TypeScript definitions for your application's routes without performing a full build. This is useful for IDE autocomplete and CI type-checking of route usage.</p>\n<p>Previously, route types were only generated during <code>next dev</code> or <code>next build</code>, which meant running <code>tsc --noEmit</code> directly wouldn't validate your route types. Now you can generate types independently and validate them externally:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Generate route types first, then validate with TypeScript</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> typegen</span><span style=\"color:var(--shiki-token-punctuation)\"> &amp;&amp;</span><span style=\"color:var(--shiki-token-function)\"> tsc</span><span style=\"color:var(--shiki-token-string)\"> --noEmit</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Or in CI workflows for type checking without building</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> typegen</span><span style=\"color:var(--shiki-token-punctuation)\"> &amp;&amp;</span><span style=\"color:var(--shiki-token-function)\"> npm</span><span style=\"color:var(--shiki-token-string)\"> run</span><span style=\"color:var(--shiki-token-string)\"> type-check</span></span></code></pre></div>\n<p>The following options are available for the <code>next typegen</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory on which to generate types. If not provided, the current directory will be used.</td></tr></tbody></table></div>\n<p>Output files are written to <code>&lt;distDir&gt;/types</code> (typically: <code>.next/dev/types</code> in development or <code>.next/types</code> in production):</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> typegen</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># or for a specific app</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> typegen</span><span style=\"color:var(--shiki-token-string)\"> ./apps/web</span></span></code></pre></div>\n<p>Additionally, <code>next typegen</code> generates a <code>next-env.d.ts</code> file. We recommend adding <code>next-env.d.ts</code> to your <code>.gitignore</code> file.</p>\n<p>The <code>next-env.d.ts</code> file is included into your <code>tsconfig.json</code> file, to make Next.js types available to your project.</p>\n<p>To ensure <code>next-env.d.ts</code> is present before type-checking run <code>next typegen</code>. The commands <code>next dev</code> and <code>next build</code> also generate the <code>next-env.d.ts</code> file, but it is often undesirable to run these just to type-check, for example in CI/CD environments.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: <code>next typegen</code> loads your Next.js config (<code>next.config.js</code>, <code>next.config.mjs</code>, or <code>next.config.ts</code>) using the production build phase. Ensure any required environment variables and dependencies are available so the config can load correctly.</p>\n</blockquote>\n<h3 id=\"next-upgrade-options\" data-docs-heading=\"\"><code>next upgrade</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-upgrade-options\"><span></span></a></h3>\n<p><code>next upgrade</code> upgrades your Next.js application to the latest version.</p>\n<p>The following options are available for the <code>next upgrade</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory with the Next.js application to upgrade. If not provided, the current directory will be used.</td></tr><tr><td><code>--revision &lt;revision&gt;</code></td><td>Specify a Next.js version or tag to upgrade to (e.g., <code>latest</code>, <code>canary</code>, <code>15.0.0</code>). Defaults to the release channel you have currently installed.</td></tr><tr><td><code>--verbose</code></td><td>Show verbose output during the upgrade process.</td></tr></tbody></table></div>\n<h3 id=\"next-experimental-analyze-options\" data-docs-heading=\"\"><code>next experimental-analyze</code> options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-experimental-analyze-options\"><span></span></a></h3>\n<p><code>next experimental-analyze</code> analyzes your application's bundle output using <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a>. This command helps you understand the size and composition of your bundles, including JavaScript, CSS, and other assets. This command doesn't produce an application build.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_19eqotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_19eqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_29eqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_29eqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_39eqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_39eqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_49eqotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_49eqotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> next</span><span style=\"color:var(--shiki-token-string)\"> experimental-analyze</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>By default, the command starts a local server after analysis completes, allowing you to explore your bundle composition in the browser. The analyzer lets you:</p>\n<ul>\n<li>Filter bundles by route and switch between client and server views</li>\n<li>View the full import chain showing why a module is included</li>\n<li>Trace imports across server-to-client component boundaries and dynamic imports</li>\n</ul>\n<p>See <a href=\"/docs/app/guides/package-bundling#optimizing-large-bundles\">Package Bundling</a> for optimization strategies.</p>\n<p>To write the analysis output to disk without starting the server, use the <code>--output</code> flag. The output is written to <code>.next/diagnostics/analyze</code> and contains static files that can be copied elsewhere or shared with others:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Write output to .next/diagnostics/analyze</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">npx</span><span style=\"color:var(--shiki-token-string)\"> next</span><span style=\"color:var(--shiki-token-string)\"> experimental-analyze</span><span style=\"color:var(--shiki-token-string)\"> --output</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Copy the output for comparison with a future analysis</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">cp</span><span style=\"color:var(--shiki-token-string)\"> -r</span><span style=\"color:var(--shiki-token-string)\"> .next/diagnostics/analyze</span><span style=\"color:var(--shiki-token-string)\"> ./analyze-before-refactor</span></span></code></pre></div>\n<p>The following options are available for the <code>next experimental-analyze</code> command:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>-h, --help</code></td><td>Show all available options.</td></tr><tr><td><code>[directory]</code></td><td>A directory on which to analyze the application. If not provided, the current directory will be used.</td></tr><tr><td><code>--no-mangling</code></td><td>Disables <a href=\"https://en.wikipedia.org/wiki/Name_mangling\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">mangling<span class=\"inline-flex not-prose\"></span></a>. This may affect performance and should only be used for debugging purposes.</td></tr><tr><td><code>--profile</code></td><td>Enables production <a href=\"https://react.dev/reference/react/Profiler\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">profiling for React<span class=\"inline-flex not-prose\"></span></a>. This may affect performance.</td></tr><tr><td><code>-o, --output</code></td><td>Write analysis files to disk without starting the server. Output is written to <code>.next/diagnostics/analyze</code>.</td></tr><tr><td><code>--port &lt;port&gt;</code></td><td>Specify a port number to serve the analyzer on. (default: 4000, env: PORT)</td></tr></tbody></table></div>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"debugging-prerender-errors\" data-docs-heading=\"\">Debugging prerender errors<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#debugging-prerender-errors\"><span></span></a></h3>\n<p>If you encounter prerendering errors during <code>next build</code>, you can pass the <code>--debug-prerender</code> flag to get more detailed output:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-prerender</span></span></code></pre></div>\n<p>This enables several experimental options to make debugging easier:</p>\n<ul>\n<li>Disables server code minification:<!-- -->\n<ul>\n<li><code>experimental.serverMinification = false</code></li>\n<li><code>experimental.turbopackMinify = false</code></li>\n</ul>\n</li>\n<li>Generates source maps for server bundles:<!-- -->\n<ul>\n<li><code>experimental.serverSourceMaps = true</code></li>\n</ul>\n</li>\n<li>Continues building even after the first prerender error, so you can see all issues at once:<!-- -->\n<ul>\n<li><code>experimental.prerenderEarlyExit = false</code></li>\n</ul>\n</li>\n</ul>\n<p>This helps surface more readable stack traces and code frames in the build output.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning</strong>: <code>--debug-prerender</code> is for debugging in development only. Do not deploy builds generated with <code>--debug-prerender</code> to production, as it may impact performance.</p>\n</blockquote>\n<h3 id=\"building-specific-routes\" data-docs-heading=\"\">Building specific routes<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#building-specific-routes\"><span></span></a></h3>\n<p>You can build only specific routes in the App and Pages Routers using the <code>--debug-build-paths</code> option. This is useful for faster debugging when working with large applications. The <code>--debug-build-paths</code> option accepts comma-separated file paths, supports glob patterns, and excludes any path prefixed with <code>!</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Build a specific route</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"app/page.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Build more than one route</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"app/page.tsx,pages/index.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Include route group folders in the path</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"app/(marketing)/about/page.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Use glob patterns</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"app/**/page.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"pages/*.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Exclude routes with a ! prefix</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --debug-build-paths=</span><span style=\"color:var(--shiki-token-string-expression)\">\"app/**/page.tsx,!app/admin/**\"</span></span></code></pre></div>\n<p>In projects that keep routes under <code>src/</code>, paths resolve with or without the <code>src/</code> prefix, so both <code>app/page.tsx</code> and <code>src/app/page.tsx</code> match the same route.</p>\n<h3 id=\"changing-the-default-port\" data-docs-heading=\"\">Changing the default port<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#changing-the-default-port\"><span></span></a></h3>\n<p>By default, Next.js uses <code>http://localhost:3000</code> during development and with <code>next start</code>. The default port can be changed with the <code>-p</code> option, like so:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> dev</span><span style=\"color:var(--shiki-token-string)\"> -p</span><span style=\"color:var(--shiki-token-constant)\"> 4000</span></span></code></pre></div>\n<p>Or using the <code>PORT</code> environment variable:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">PORT</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">4000</span><span style=\"color:var(--shiki-token-function)\"> next</span><span style=\"color:var(--shiki-token-string)\"> dev</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: <code>PORT</code> cannot be set in <code>.env</code> as booting up the HTTP server happens before any other code is initialized.</p>\n</blockquote>\n<h3 id=\"using-https-during-development\" data-docs-heading=\"\">Using HTTPS during development<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-https-during-development\"><span></span></a></h3>\n<p>For certain use cases like webhooks or authentication, you can use <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/HTTPS\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">HTTPS<span class=\"inline-flex not-prose\"></span></a> to have a secure environment on <code>localhost</code>. Next.js can generate a self-signed certificate with <code>next dev</code> using the <code>--experimental-https</code> flag:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> dev</span><span style=\"color:var(--shiki-token-string)\"> --experimental-https</span></span></code></pre></div>\n<p>With the generated certificate, the Next.js development server will exist at <code>https://localhost:3000</code>. The default port <code>3000</code> is used unless a port is specified with <code>-p</code>, <code>--port</code>, or <code>PORT</code>.</p>\n<p>You can also provide a custom certificate and key with <code>--experimental-https-key</code> and <code>--experimental-https-cert</code>. Optionally, you can provide a custom CA certificate with <code>--experimental-https-ca</code> as well.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> dev</span><span style=\"color:var(--shiki-token-string)\"> --experimental-https</span><span style=\"color:var(--shiki-token-string)\"> --experimental-https-key</span><span style=\"color:var(--shiki-token-string)\"> ./certificates/localhost-key.pem</span><span style=\"color:var(--shiki-token-string)\"> --experimental-https-cert</span><span style=\"color:var(--shiki-token-string)\"> ./certificates/localhost.pem</span></span></code></pre></div>\n<p><code>next dev --experimental-https</code> is only intended for development and creates a locally trusted certificate with <a href=\"https://github.com/FiloSottile/mkcert\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>mkcert</code><span class=\"inline-flex not-prose\"></span></a>. In production, use properly issued certificates from trusted authorities.</p>\n<h3 id=\"configuring-a-timeout-for-downstream-proxies\" data-docs-heading=\"\">Configuring a timeout for downstream proxies<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#configuring-a-timeout-for-downstream-proxies\"><span></span></a></h3>\n<p>When deploying Next.js behind a downstream proxy (e.g. a load-balancer like AWS ELB/ALB), it's important to configure Next's underlying HTTP server with <a href=\"https://nodejs.org/api/http.html#http_server_keepalivetimeout\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">keep-alive timeouts<span class=\"inline-flex not-prose\"></span></a> that are <em>larger</em> than the downstream proxy's timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the downstream proxy. This results in a proxy error whenever it attempts to reuse a connection that Node.js has already terminated.</p>\n<p>To configure the timeout values for the production Next.js server, pass <code>--keepAliveTimeout</code> (in milliseconds) to <code>next start</code>, like so:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> start</span><span style=\"color:var(--shiki-token-string)\"> --keepAliveTimeout</span><span style=\"color:var(--shiki-token-constant)\"> 70000</span></span></code></pre></div>\n<h3 id=\"passing-nodejs-arguments\" data-docs-heading=\"\">Passing Node.js arguments<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#passing-nodejs-arguments\"><span></span></a></h3>\n<p>You can pass any <a href=\"https://nodejs.org/api/cli.html#cli_node_options_options\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">node arguments<span class=\"inline-flex not-prose\"></span></a> to <code>next</code> commands. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NODE_OPTIONS</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">'--throw-deprecation'</span><span style=\"color:var(--shiki-token-function)\"> next</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NODE_OPTIONS</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">'-r esm'</span><span style=\"color:var(--shiki-token-function)\"> next</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NODE_OPTIONS</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">'--inspect'</span><span style=\"color:var(--shiki-token-function)\"> next</span></span></code></pre></div>\n<h3 id=\"cpu-profiling\" data-docs-heading=\"\">CPU profiling<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cpu-profiling\"><span></span></a></h3>\n<p>You can capture CPU profiles to analyze performance bottlenecks in your Next.js application. The <code>--experimental-cpu-prof</code> flag enables V8's built-in CPU profiler and saves profiles to <code>.next-profiles/</code> when the process exits:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Profile the build process</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> build</span><span style=\"color:var(--shiki-token-string)\"> --experimental-cpu-prof</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Profile the dev server (profile saved on Ctrl+C or SIGTERM)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> dev</span><span style=\"color:var(--shiki-token-string)\"> --experimental-cpu-prof</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># Profile the production server</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> start</span><span style=\"color:var(--shiki-token-string)\"> --experimental-cpu-prof</span></span></code></pre></div>\n<p>The generated <code>.cpuprofile</code> files can be opened in Chrome DevTools (Performance tab → Load profile) or other V8-compatible profiling tools.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Profile files are named with a descriptive prefix and timestamp. The profiles generated depend on the command:</p>\n<p><strong><code>next dev</code>:</strong></p>\n<ul>\n<li><code>dev-main-*</code> - Parent process (dev server orchestration)</li>\n<li><code>dev-server-*</code> - Child server process (request handling and rendering) - this is typically what you want to analyze</li>\n</ul>\n<p><strong><code>next build</code> (Turbopack):</strong></p>\n<ul>\n<li><code>build-main-*</code> - Main build orchestration process</li>\n<li><code>build-turbopack-*</code> - Turbopack compilation worker</li>\n</ul>\n<p><strong><code>next build</code> (Webpack):</strong></p>\n<ul>\n<li><code>build-main-*</code> - Main build orchestration process</li>\n<li><code>build-webpack-client-*</code> - Client bundle compilation worker</li>\n<li><code>build-webpack-server-*</code> - Server bundle compilation worker</li>\n<li><code>build-webpack-edge-server-*</code> - Edge runtime compilation worker</li>\n</ul>\n<p><strong><code>next start</code>:</strong></p>\n<ul>\n<li><code>start-main-*</code> - Production server process</li>\n</ul>\n</blockquote>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.1.0</code></td><td>Add the <code>next upgrade</code> command</td></tr><tr><td><code>v16.1.0</code></td><td>Add the <code>next experimental-analyze</code> command</td></tr><tr><td><code>v16.0.0</code></td><td>The JS bundle size metrics have been removed from <code>next build</code></td></tr><tr><td><code>v15.5.0</code></td><td>Add the <code>next typegen</code> command</td></tr><tr><td><code>v15.4.0</code></td><td>Add <code>--debug-prerender</code> option for <code>next build</code> to help debug prerender errors.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components",
    "title": "API Reference: Components | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Components</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/font\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Font</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Optimizing loading web fonts with the built-in `next/font` loaders.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/form\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Form Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the `&lt;Form&gt;` component to handle form submissions and search params updates with client-side navigation.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/image\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Image Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Optimize Images in your Next.js Application using the built-in `next/image` Component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/link\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Link Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable fast client-side navigation with the built-in `next/link` component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/script\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Script Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Optimize third-party scripts in your Next.js application using the built-in `next/script` Component.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components/font",
    "title": "Components: Font | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Font Module</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 6, 2025</div>\n<p><a href=\"/docs/app/api-reference/components/font\"><code>next/font</code></a> automatically optimizes your fonts (including custom fonts) and removes external network requests for improved privacy and performance.</p>\n<p>It includes <strong>built-in automatic self-hosting</strong> for any font file. This means you can optimally load web fonts with no <a href=\"https://web.dev/articles/cls\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">layout shift<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>You can also conveniently use all <a href=\"https://fonts.google.com/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Google Fonts<span class=\"inline-flex not-prose\"></span></a>. CSS and font files are downloaded at build time and self-hosted with the rest of your static assets. <strong>No requests are sent to Google by the browser.</strong></p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// If loading a variable font, you don't need to specify the font weight</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>🎥 Watch:</strong> Learn more about using <code>next/font</code> → <a href=\"https://www.youtube.com/watch?v=L8_98i_bMMA\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">YouTube (6 minutes)<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Key</th><th class=\"min-w-[12ch]\"><code>font/google</code></th><th class=\"min-w-[12ch]\"><code>font/local</code></th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th></tr></thead><tbody><tr><td><a href=\"#src\"><code>src</code></a></td><td><span class=\"inline-flex align-middle text-gray-900\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>String or Array of Objects</td><td>Yes</td></tr><tr><td><a href=\"#weight\"><code>weight</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>String or Array</td><td>Required/Optional</td></tr><tr><td><a href=\"#style\"><code>style</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>String or Array</td><td>-</td></tr><tr><td><a href=\"#subsets\"><code>subsets</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-gray-900\"></span></td><td>Array of Strings</td><td>-</td></tr><tr><td><a href=\"#axes\"><code>axes</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-gray-900\"></span></td><td>Array of Strings</td><td>-</td></tr><tr><td><a href=\"#display\"><code>display</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>String</td><td>-</td></tr><tr><td><a href=\"#preload\"><code>preload</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#fallback\"><code>fallback</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>Array of Strings</td><td>-</td></tr><tr><td><a href=\"#adjustfontfallback\"><code>adjustFontFallback</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>Boolean or String</td><td>-</td></tr><tr><td><a href=\"#variable\"><code>variable</code></a></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>String</td><td>-</td></tr><tr><td><a href=\"#declarations\"><code>declarations</code></a></td><td><span class=\"inline-flex align-middle text-gray-900\"></span></td><td><span class=\"inline-flex align-middle text-green-600\"></span></td><td>Array of Objects</td><td>-</td></tr></tbody></table></div>\n<h3 id=\"src\" data-docs-heading=\"\"><code>src</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#src\"><span></span></a></h3>\n<p>The path of the font file as a string or an array of objects (with type <code>Array&lt;{path: string, weight?: string, style?: string}&gt;</code>) relative to the directory where the font loader function is called.</p>\n<p>Used in <code>next/font/local</code></p>\n<ul>\n<li>Required</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>src:'./fonts/my-font.woff2'</code> where <code>my-font.woff2</code> is placed in a directory named <code>fonts</code> inside the <code>app</code> directory</li>\n<li><code>src:[{path: './inter/Inter-Thin.ttf', weight: '100',},{path: './inter/Inter-Regular.ttf',weight: '400',},{path: './inter/Inter-Bold-Italic.ttf', weight: '700',style: 'italic',},]</code></li>\n<li>if the font loader function is called in <code>app/page.tsx</code> using <code>src:'../styles/fonts/my-font.ttf'</code>, then <code>my-font.ttf</code> is placed in <code>styles/fonts</code> at the root of the project</li>\n</ul>\n<h3 id=\"weight\" data-docs-heading=\"\"><code>weight</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#weight\"><span></span></a></h3>\n<p>The font <a href=\"https://fonts.google.com/knowledge/glossary/weight\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>weight</code><span class=\"inline-flex not-prose\"></span></a> with the following possibilities:</p>\n<ul>\n<li>A string with possible values of the weights available for the specific font or a range of values if it's a <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable<span class=\"inline-flex not-prose\"></span></a> font</li>\n<li>An array of weight values if the font is not a <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable google font<span class=\"inline-flex not-prose\"></span></a>. It applies to <code>next/font/google</code> only.</li>\n</ul>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Required if the font being used is <strong>not</strong> <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>weight: '400'</code>: A string for a single weight value - for the font <a href=\"https://fonts.google.com/specimen/Inter?query=inter\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Inter</code><span class=\"inline-flex not-prose\"></span></a>, the possible values are <code>'100'</code>, <code>'200'</code>, <code>'300'</code>, <code>'400'</code>, <code>'500'</code>, <code>'600'</code>, <code>'700'</code>, <code>'800'</code>, <code>'900'</code> or <code>'variable'</code> where <code>'variable'</code> is the default)</li>\n<li><code>weight: '100 900'</code>: A string for the range between <code>100</code> and <code>900</code> for a variable font</li>\n<li><code>weight: ['100','400','900']</code>: An array of 3 possible values for a non variable font</li>\n</ul>\n<h3 id=\"style\" data-docs-heading=\"\"><code>style</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#style\"><span></span></a></h3>\n<p>The font <a href=\"https://developer.mozilla.org/docs/Web/CSS/font-style\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>style</code><span class=\"inline-flex not-prose\"></span></a> with the following possibilities:</p>\n<ul>\n<li>A string <a href=\"https://developer.mozilla.org/docs/Web/CSS/font-style#values\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">value<span class=\"inline-flex not-prose\"></span></a> with default value of <code>'normal'</code></li>\n<li>An array of style values if the font is not a <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable google font<span class=\"inline-flex not-prose\"></span></a>. It applies to <code>next/font/google</code> only.</li>\n</ul>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>style: 'italic'</code>: A string - it can be <code>normal</code> or <code>italic</code> for <code>next/font/google</code></li>\n<li><code>style: 'oblique'</code>: A string - it can take any value for <code>next/font/local</code> but is expected to come from <a href=\"https://developer.mozilla.org/docs/Web/CSS/font-style\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">standard font styles<span class=\"inline-flex not-prose\"></span></a></li>\n<li><code>style: ['italic','normal']</code>: An array of 2 values for <code>next/font/google</code> - the values are from <code>normal</code> and <code>italic</code></li>\n</ul>\n<h3 id=\"subsets\" data-docs-heading=\"\"><code>subsets</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#subsets\"><span></span></a></h3>\n<p>The font <a href=\"https://fonts.google.com/knowledge/glossary/subsetting\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>subsets</code><span class=\"inline-flex not-prose\"></span></a> defined by an array of string values with the names of each subset you would like to be <a href=\"/docs/app/api-reference/components/font#specifying-a-subset\">preloaded</a>. Fonts specified via <code>subsets</code> will have a link preload tag injected into the head when the <a href=\"#preload\"><code>preload</code></a> option is true, which is the default.</p>\n<p>Used in <code>next/font/google</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>subsets: ['latin']</code>: An array with the subset <code>latin</code></li>\n</ul>\n<p>You can find a list of all subsets on the Google Fonts page for your font.</p>\n<h3 id=\"axes\" data-docs-heading=\"\"><code>axes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#axes\"><span></span></a></h3>\n<p>Some variable fonts have extra <code>axes</code> that can be included. By default, only the font weight is included to keep the file size down. The possible values of <code>axes</code> depend on the specific font.</p>\n<p>Used in <code>next/font/google</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>axes: ['slnt']</code>: An array with value <code>slnt</code> for the <code>Inter</code> variable font which has <code>slnt</code> as additional <code>axes</code> as shown <a href=\"https://fonts.google.com/variablefonts?vfquery=inter#font-families\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">here<span class=\"inline-flex not-prose\"></span></a>. You can find the possible <code>axes</code> values for your font by using the filter on the <a href=\"https://fonts.google.com/variablefonts#font-families\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Google variable fonts page<span class=\"inline-flex not-prose\"></span></a> and looking for axes other than <code>wght</code></li>\n</ul>\n<h3 id=\"display\" data-docs-heading=\"\"><code>display</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#display\"><span></span></a></h3>\n<p>The font <a href=\"https://developer.mozilla.org/docs/Web/CSS/@font-face/font-display\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>display</code><span class=\"inline-flex not-prose\"></span></a> with possible string <a href=\"https://developer.mozilla.org/docs/Web/CSS/@font-face/font-display#values\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">values<span class=\"inline-flex not-prose\"></span></a> of <code>'auto'</code>, <code>'block'</code>, <code>'swap'</code>, <code>'fallback'</code> or <code>'optional'</code> with default value of <code>'swap'</code>.</p>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>display: 'optional'</code>: A string assigned to the <code>optional</code> value</li>\n</ul>\n<h3 id=\"preload\" data-docs-heading=\"\"><code>preload</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#preload\"><span></span></a></h3>\n<p>A boolean value that specifies whether the font should be <a href=\"/docs/app/api-reference/components/font#preloading\">preloaded</a> or not. The default is <code>true</code>.</p>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>preload: false</code></li>\n</ul>\n<h3 id=\"fallback\" data-docs-heading=\"\"><code>fallback</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#fallback\"><span></span></a></h3>\n<p>The fallback font to use if the font cannot be loaded. An array of strings of fallback fonts with no default.</p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<p>Examples:</p>\n<ul>\n<li><code>fallback: ['system-ui', 'arial']</code>: An array setting the fallback fonts to <code>system-ui</code> or <code>arial</code></li>\n</ul>\n<h3 id=\"adjustfontfallback\" data-docs-heading=\"\"><code>adjustFontFallback</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#adjustfontfallback\"><span></span></a></h3>\n<ul>\n<li>For <code>next/font/google</code>: A boolean value that sets whether an automatic fallback font should be used to reduce <a href=\"https://web.dev/cls/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Cumulative Layout Shift<span class=\"inline-flex not-prose\"></span></a>. The default is <code>true</code>.</li>\n<li>For <code>next/font/local</code>: A string or boolean <code>false</code> value that sets whether an automatic fallback font should be used to reduce <a href=\"https://web.dev/cls/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Cumulative Layout Shift<span class=\"inline-flex not-prose\"></span></a>. The possible values are <code>'Arial'</code>, <code>'Times New Roman'</code> or <code>false</code>. The default is <code>'Arial'</code>.</li>\n</ul>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>adjustFontFallback: false</code>: for <code>next/font/google</code></li>\n<li><code>adjustFontFallback: 'Times New Roman'</code>: for <code>next/font/local</code></li>\n</ul>\n<h3 id=\"variable\" data-docs-heading=\"\"><code>variable</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#variable\"><span></span></a></h3>\n<p>A string value to define the CSS variable name to be used if the style is applied with the <a href=\"#css-variables\">CSS variable method</a>.</p>\n<p>Used in <code>next/font/google</code> and <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>variable: '--my-font'</code>: The CSS variable <code>--my-font</code> is declared</li>\n</ul>\n<h3 id=\"declarations\" data-docs-heading=\"\"><code>declarations</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#declarations\"><span></span></a></h3>\n<p>An array of font face <a href=\"https://developer.mozilla.org/docs/Web/CSS/@font-face#descriptors\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">descriptor<span class=\"inline-flex not-prose\"></span></a> key-value pairs that define the generated <code>@font-face</code> further.</p>\n<p>Used in <code>next/font/local</code></p>\n<ul>\n<li>Optional</li>\n</ul>\n<p>Examples:</p>\n<ul>\n<li><code>declarations: [{ prop: 'ascent-override', value: '90%' }]</code></li>\n</ul>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h2 id=\"google-fonts\" data-docs-heading=\"\">Google Fonts<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#google-fonts\"><span></span></a></h2>\n<p>To use a Google font, import it from <code>next/font/google</code> as a function. We recommend using <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable fonts<span class=\"inline-flex not-prose\"></span></a> for the best performance and flexibility.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// If loading a variable font, you don't need to specify the font weight</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>If you can't use a variable font, you will <strong>need to specify a weight</strong>:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Roboto } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> roboto</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Roboto</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '400'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">roboto</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>You can specify multiple weights and/or styles by using an array:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> roboto</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Roboto</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'400'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '700'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'normal'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'italic'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Use an underscore (_) for font names with multiple words. E.g. <code>Roboto Mono</code> should be imported as <code>Roboto_Mono</code>.</p>\n</blockquote>\n<!-- -->\n<h3 id=\"specifying-a-subset\" data-docs-heading=\"\">Specifying a subset<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#specifying-a-subset\"><span></span></a></h3>\n<p>Google Fonts are automatically <a href=\"https://fonts.google.com/knowledge/glossary/subsetting\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">subset<span class=\"inline-flex not-prose\"></span></a>. This reduces the size of the font file and improves performance. You'll need to define which of these subsets you want to preload. Failing to specify any subsets while <a href=\"/docs/app/api-reference/components/font#preload\"><code>preload</code></a> is <code>true</code> will result in a warning.</p>\n<p>This can be done by adding it to the function call:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({ subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">] })</span></span></code></pre></div>\n<!-- -->\n<p>View the <a href=\"/docs/app/api-reference/components/font\">Font API Reference</a> for more information.</p>\n<h2 id=\"using-multiple-fonts\" data-docs-heading=\"\">Using Multiple Fonts<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-multiple-fonts\"><span></span></a></h2>\n<p>You can import and use multiple fonts in your application. There are two approaches you can take.</p>\n<p>The first approach is to create a utility function that exports a font, imports it, and applies its <code>className</code> where needed. This ensures the font is preloaded only when it's rendered:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/fonts.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> Roboto_Mono } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> const</span><span style=\"color:var(--shiki-token-constant)\"> roboto_mono</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Roboto_Mono</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<!-- -->\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { inter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './fonts'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Layout</span><span style=\"color:var(--shiki-color-text)\">({ children }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { roboto_mono } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './fonts'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">roboto_mono</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;My page&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>In the example above, <code>Inter</code> will be applied globally, and <code>Roboto Mono</code> can be imported and applied as needed.</p>\n<p>Alternatively, you can create a <a href=\"/docs/app/api-reference/components/font#variable\">CSS variable</a> and use it with your preferred CSS solution:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> Roboto_Mono } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> styles </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './global.css'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  variable</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '--font-inter'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> roboto_mono</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Roboto_Mono</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  variable</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '--font-roboto-mono'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.variable</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-keyword)\"> ${</span><span style=\"color:var(--shiki-token-constant)\">roboto_mono</span><span style=\"color:var(--shiki-color-text)\">.variable</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;My App&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/global.css</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  font-family</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> var</span><span style=\"color:var(--shiki-token-constant)\">(--font-inter)</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  font-family</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> var</span><span style=\"color:var(--shiki-token-constant)\">(--font-roboto-mono)</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>In the example above, <code>Inter</code> will be applied globally, and any <code>&lt;h1&gt;</code> tags will be styled with <code>Roboto Mono</code>.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Recommendation</strong>: Use multiple fonts conservatively since each new font is an additional resource the client has to download.</p>\n</blockquote>\n<h3 id=\"local-fonts\" data-docs-heading=\"\">Local Fonts<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#local-fonts\"><span></span></a></h3>\n<p>Import <code>next/font/local</code> and specify the <code>src</code> of your local font file. We recommend using <a href=\"https://fonts.google.com/variablefonts\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">variable fonts<span class=\"inline-flex not-prose\"></span></a> for the best performance and flexibility.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> localFont </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/local'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Font files can be colocated inside of `app`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> myFont</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> localFont</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './my-font.woff2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">myFont</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>If you want to use multiple files for a single font family, <code>src</code> can be an array:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> roboto</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> localFont</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './Roboto-Regular.woff2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '400'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'normal'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './Roboto-Italic.woff2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '400'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'italic'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './Roboto-Bold.woff2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '700'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'normal'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './Roboto-BoldItalic.woff2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '700'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'italic'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<p>View the <a href=\"/docs/app/api-reference/components/font\">Font API Reference</a> for more information.</p>\n<h3 id=\"with-tailwind-css\" data-docs-heading=\"\">With Tailwind CSS<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-tailwind-css\"><span></span></a></h3>\n<p><code>next/font</code> integrates seamlessly with <a href=\"https://tailwindcss.com/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Tailwind CSS<span class=\"inline-flex not-prose\"></span></a> using <a href=\"/docs/app/api-reference/components/font#css-variables\">CSS variables</a>.</p>\n<p>In the example below, we use the <code>Inter</code> and <code>Roboto_Mono</code> fonts from <code>next/font/google</code> (you can use any Google Font or Local Font). Use the <code>variable</code> option to define a CSS variable name, such as <code>inter</code> and <code>roboto_mono</code> for these fonts, respectively. Then, apply <code>inter.variable</code> and <code>roboto_mono.variable</code> to include the CSS variables in your HTML document.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: You can add these variables to the <code>&lt;html&gt;</code> or <code>&lt;body&gt;</code> tag, depending on your preference, styling needs or project requirements.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> Roboto_Mono } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  variable</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '--font-inter'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> roboto_mono</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Roboto_Mono</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  subsets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'latin'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'swap'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  variable</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '--font-roboto-mono'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.variable</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-keyword)\"> ${</span><span style=\"color:var(--shiki-token-constant)\">roboto_mono</span><span style=\"color:var(--shiki-color-text)\">.variable</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\"> antialiased`</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>Finally, add the CSS variable to your <a href=\"/docs/app/getting-started/css#tailwind-css\">Tailwind CSS config</a>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">global.css</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">@import</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tailwindcss'</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">@theme</span><span style=\"color:var(--shiki-color-text)\"> inline {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  --font-sans: var(--font-inter);</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  --font-mono: var(--font-roboto-mono);</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"tailwind-css-v3\" data-docs-heading=\"\">Tailwind CSS v3<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#tailwind-css-v3\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">tailwind.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('tailwindcss').Config}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  content</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    './pages/**/*.{js,ts,jsx,tsx}'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    './components/**/*.{js,ts,jsx,tsx}'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    './app/**/*.{js,ts,jsx,tsx}'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  theme</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    extend</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      fontFamily</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        sans</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'var(--font-inter)'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        mono</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'var(--font-roboto-mono)'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  plugins</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> []</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can now use the <code>font-sans</code> and <code>font-mono</code> utility classes to apply the font to your elements.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> class</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"font-sans ...\"</span><span style=\"color:var(--shiki-color-text)\">&gt;The quick brown fox ...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> class</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"font-mono ...\"</span><span style=\"color:var(--shiki-color-text)\">&gt;The quick brown fox ...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<h3 id=\"applying-styles\" data-docs-heading=\"\">Applying Styles<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#applying-styles\"><span></span></a></h3>\n<p>You can apply the font styles in three ways:</p>\n<ul>\n<li><a href=\"#classname\"><code>className</code></a></li>\n<li><a href=\"#style-1\"><code>style</code></a></li>\n<li><a href=\"#css-variables\">CSS Variables</a></li>\n</ul>\n<h4 id=\"classname\" data-docs-heading=\"\"><code>className</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#classname\"><span></span></a></h4>\n<p>Returns a read-only CSS <code>className</code> for the loaded font to be passed to an HTML element.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;Hello, Next.js!&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<h4 id=\"style-1\" data-docs-heading=\"\"><code>style</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#style-1\"><span></span></a></h4>\n<p>Returns a read-only CSS <code>style</code> object for the loaded font to be passed to an HTML element, including <code>style.fontFamily</code> to access the font family name and fallback fonts.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.style}&gt;Hello World&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<h4 id=\"css-variables\" data-docs-heading=\"\">CSS Variables<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#css-variables\"><span></span></a></h4>\n<p>If you would like to set your styles in an external style sheet and specify additional options there, use the CSS variable method.</p>\n<p>In addition to importing the font, also import the CSS file where the CSS variable is defined and set the variable option of the font loader object as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> styles </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../styles/component.module.css'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  variable</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '--font-inter'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span></code></pre></div>\n<!-- -->\n<p>To use the font, set the <code>className</code> of the parent container of the text you would like to style to the font loader's <code>variable</code> value and the <code>className</code> of the text to the <code>styles</code> property from the external CSS file.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.variable}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">styles</span><span style=\"color:var(--shiki-color-text)\">.text}&gt;Hello World&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<!-- -->\n<p>Define the <code>text</code> selector class in the <code>component.module.css</code> CSS file as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">styles/component.module.css</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">.text</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  font-family</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> var</span><span style=\"color:var(--shiki-token-constant)\">(--font-inter)</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  font-weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 200</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  font-style</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> italic</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>In the example above, the text <code>Hello World</code> is styled using the <code>Inter</code> font and the generated font fallback with <code>font-weight: 200</code> and <code>font-style: italic</code>.</p>\n<h3 id=\"using-a-font-definitions-file\" data-docs-heading=\"\">Using a font definitions file<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-a-font-definitions-file\"><span></span></a></h3>\n<p>Every time you call the <code>localFont</code> or Google font function, that font will be hosted as one instance in your application. Therefore, if you need to use the same font in multiple places, you should load it in one place and import the related font object where you need it. This is done using a font definitions file.</p>\n<p>For example, create a <code>fonts.ts</code> file in a <code>styles</code> folder at the root of your app directory.</p>\n<p>Then, specify your font definitions as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">styles/fonts.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> Lora</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> Source_Sans_3 } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/google'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> localFont </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/font/local'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// define your variable fonts</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> inter</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Inter</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> lora</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Lora</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// define 2 weights of a non-variable font</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> sourceCodePro400</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Source_Sans_3</span><span style=\"color:var(--shiki-color-text)\">({ weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '400'</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> sourceCodePro700</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Source_Sans_3</span><span style=\"color:var(--shiki-color-text)\">({ weight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '700'</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// define a custom local font where GreatVibes-Regular.ttf is stored in the styles folder</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> greatVibes</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> localFont</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './GreatVibes-Regular.ttf'</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-color-text)\"> { inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> lora</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sourceCodePro400</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sourceCodePro700</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> greatVibes }</span></span></code></pre></div>\n<!-- -->\n<p>You can now use these definitions in your code as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { inter</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> lora</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sourceCodePro700</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> greatVibes } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../styles/fonts'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">inter</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;Hello world using Inter font&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">lora</span><span style=\"color:var(--shiki-color-text)\">.style}&gt;Hello world using Lora font&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">sourceCodePro700</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        Hello world using Source_Sans_3 font with weight 700</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">greatVibes</span><span style=\"color:var(--shiki-color-text)\">.className}&gt;My title in Great Vibes font&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>To make it easier to access the font definitions in your code, you can define a path alias in your <code>tsconfig.json</code> or <code>jsconfig.json</code> files as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">tsconfig.json</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"compilerOptions\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    \"paths\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      \"@/fonts\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">\"./styles/fonts\"</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can now import any font definition as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/about/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { greatVibes</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sourceCodePro400 } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@/fonts'</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"preloading\" data-docs-heading=\"\">Preloading<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#preloading\"><span></span></a></h3>\n<p>When a font function is called on a page of your site, it is not globally available and preloaded on all routes. Rather, the font is only preloaded on the related routes based on the type of file where it is used:</p><ul>\n<li>If it's a <a href=\"/docs/app/api-reference/file-conventions/page\">unique page</a>, it is preloaded on the unique route for that page.</li>\n<li>If it's a <a href=\"/docs/app/api-reference/file-conventions/layout\">layout</a>, it is preloaded on all the routes wrapped by the layout.</li>\n<li>If it's the <a href=\"/docs/app/api-reference/file-conventions/layout#root-layout\">root layout</a>, it is preloaded on all routes.</li>\n</ul>\n<!-- -->\n<h2 id=\"version-changes\" data-docs-heading=\"\">Version Changes<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-changes\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.2.0</code></td><td><code>@next/font</code> renamed to <code>next/font</code>. Installation no longer required.</td></tr><tr><td><code>v13.0.0</code></td><td><code>@next/font</code> was added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components/form",
    "title": "Components: Form Component | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Form Component</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 25, 2026</div><p>The <code>&lt;Form&gt;</code> component extends the HTML <code>&lt;form&gt;</code> element to provide <a href=\"/docs/app/getting-started/linking-and-navigating#prefetching\"><strong>prefetching</strong></a> of <a href=\"/docs/app/api-reference/file-conventions/loading\">loading UI</a>,<!-- --> <strong>client-side navigation</strong> on submission, and <strong>progressive enhancement</strong>.</p>\n<p>It's useful for forms that update URL search params as it reduces the boilerplate code needed to achieve the above.</p>\n<p>Basic usage:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/ui/search.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Form </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/form'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/search\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* On submission, the input value will be appended to</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">          the URL, e.g. /search?query=abc */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">input</span><span style=\"color:var(--shiki-token-function)\"> name</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"query\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"submit\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Submit&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The behavior of the <code>&lt;Form&gt;</code> component depends on whether the <code>action</code> prop is passed a <code>string</code> or <code>function</code>.</p>\n<ul>\n<li>When <code>action</code> is a <strong>string</strong>, the <code>&lt;Form&gt;</code> behaves like a native HTML form that uses a <strong><code>GET</code></strong> method. The form data is encoded into the URL as search params, and when the form is submitted, it navigates to the specified URL. In addition, Next.js:<!-- -->\n<ul>\n<li><a href=\"/docs/app/getting-started/linking-and-navigating#prefetching\">Prefetches</a> the path when the form becomes visible, this preloads shared UI (e.g. <code>layout.js</code> and <code>loading.js</code>), resulting in faster navigation.</li>\n<li>Performs a <a href=\"/docs/app/getting-started/linking-and-navigating#client-side-transitions\">client-side navigation</a> instead of a full page reload when the form is submitted. This retains shared UI and client-side state.</li>\n</ul>\n</li>\n<li>When <code>action</code> is a <strong>function</strong> (Server Action), <code>&lt;Form&gt;</code> behaves like a <a href=\"https://react.dev/reference/react-dom/components/form\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">React form<span class=\"inline-flex not-prose\"></span></a>, executing the action when the form is submitted.</li>\n</ul>\n<!-- -->\n<h3 id=\"action-string-props\" data-docs-heading=\"\"><code>action</code> (string) Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#action-string-props\"><span></span></a></h3>\n<!-- -->\n<p>When <code>action</code> is a string, the <code>&lt;Form&gt;</code> component supports the following props:</p><div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Prop</th><th class=\"min-w-[12ch]\">Example</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th></tr></thead><tbody><tr><td><code>action</code></td><td><code>action=\"/search\"</code></td><td><code>string</code> (URL or relative path)</td><td>Yes</td></tr><tr><td><code>replace</code></td><td><code>replace={false}</code></td><td><code>boolean</code></td><td>-</td></tr><tr><td><code>scroll</code></td><td><code>scroll={true}</code></td><td><code>boolean</code></td><td>-</td></tr><tr><td><code>prefetch</code></td><td><code>prefetch={true}</code></td><td><code>boolean</code></td><td>-</td></tr></tbody></table></div><ul>\n<li><strong><code>action</code></strong>: The URL or path to navigate to when the form is submitted.<!-- -->\n<ul>\n<li>An empty string <code>\"\"</code> will navigate to the same route with updated search params.</li>\n</ul>\n</li>\n<li><strong><code>replace</code></strong>: Replaces the current history state instead of pushing a new one to the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">browser's history<span class=\"inline-flex not-prose\"></span></a> stack. Default is <code>false</code>.</li>\n<li><strong><code>scroll</code></strong>: Controls the scroll behavior during navigation. Defaults to <code>true</code>, this means it will scroll to the top of the new route, and maintain the scroll position for backwards and forwards navigation.</li>\n<li><strong><code>prefetch</code></strong>: Controls whether the path should be prefetched when the form becomes visible in the user's viewport. Defaults to <code>true</code>.</li>\n</ul><h3 id=\"action-function-props\" data-docs-heading=\"\"><code>action</code> (function) Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#action-function-props\"><span></span></a></h3><p>When <code>action</code> is a function, the <code>&lt;Form&gt;</code> component supports the following prop:</p><div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Prop</th><th class=\"min-w-[12ch]\">Example</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th></tr></thead><tbody><tr><td><code>action</code></td><td><code>action={myAction}</code></td><td><code>function</code> (Server Action)</td><td>Yes</td></tr></tbody></table></div><ul>\n<li><strong><code>action</code></strong>: The Server Action to be called when the form is submitted. See the <a href=\"https://react.dev/reference/react-dom/components/form#props\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">React docs<span class=\"inline-flex not-prose\"></span></a> for more.</li>\n</ul><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: When <code>action</code> is a function, the <code>replace</code> and <code>scroll</code> props are ignored.</p>\n</blockquote>\n<h3 id=\"caveats\" data-docs-heading=\"\">Caveats<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caveats\"><span></span></a></h3>\n<ul>\n<li><strong><code>formAction</code></strong>: Can be used in a <code>&lt;button&gt;</code> or <code>&lt;input type=\"submit\"&gt;</code> fields to override the <code>action</code> prop. Next.js will perform a client-side navigation, however, this approach doesn't support prefetching.<!-- -->\n<ul>\n<li>When using <a href=\"/docs/app/api-reference/config/next-config-js/basePath\"><code>basePath</code></a>, you must also include it in the <code>formAction</code> path. e.g. <code>formAction=\"/base-path/search\"</code>.</li>\n</ul>\n</li>\n<li><strong><code>key</code></strong>: Passing a <code>key</code> prop to a string <code>action</code> is not supported. If you'd like to trigger a re-render or perform a mutation, consider using a function <code>action</code> instead.</li>\n</ul>\n<ul>\n<li><strong><code>onSubmit</code></strong>: Can be used to handle form submission logic. However, calling <code>event.preventDefault()</code> will override <code>&lt;Form&gt;</code> behavior such as navigating to the specified URL.</li>\n<li><strong><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#method\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>method</code><span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#enctype\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>encType</code><span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#target\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>target</code><span class=\"inline-flex not-prose\"></span></a></strong>: Are not supported as they override <code>&lt;Form&gt;</code> behavior.<!-- -->\n<ul>\n<li>Similarly, <code>formMethod</code>, <code>formEncType</code>, and <code>formTarget</code> can be used to override the <code>method</code>, <code>encType</code>, and <code>target</code> props respectively, and using them will fallback to native browser behavior.</li>\n<li>If you need to use these props, use the HTML <code>&lt;form&gt;</code> element instead.</li>\n</ul>\n</li>\n<li><strong><code>&lt;input type=\"file\"&gt;</code></strong>: Using this input type when the <code>action</code> is a string will match browser behavior by submitting the filename instead of the file object.</li>\n</ul>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2><h3 id=\"search-form-that-leads-to-a-search-result-page\" data-docs-heading=\"\">Search form that leads to a search result page<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#search-form-that-leads-to-a-search-result-page\"><span></span></a></h3><p>You can create a search form that navigates to a search results page by passing the path as an <code>action</code>:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Form </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/form'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/search\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">input</span><span style=\"color:var(--shiki-token-function)\"> name</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"query\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"submit\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Submit&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>When the user updates the query input field and submits the form, the form data will be encoded into the URL as search params, e.g. <code>/search?query=abc</code>.</p><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you pass an empty string <code>\"\"</code> to <code>action</code>, the form will navigate to the same route with updated search params.</p>\n</blockquote><p>On the results page, you can access the query using the <a href=\"/docs/app/api-reference/file-conventions/page#searchparams-optional\"><code>searchParams</code></a> <code>page.js</code> prop and use it to fetch data from an external source.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/search/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { getSearchResults } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@/lib/search'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> SearchPage</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  searchParams</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  searchParams</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;{ [key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">[] </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-color-text)\"> }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> results</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getSearchResults</span><span style=\"color:var(--shiki-color-text)\">((</span><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-color-text)\"> searchParams).query)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>When the <code>&lt;Form&gt;</code> becomes visible in the user's viewport, shared UI (such as <code>layout.js</code> and <code>loading.js</code>) on the <code>/search</code> page will be prefetched. On submission, the form will immediately navigate to the new route and show loading UI while the results are being fetched. You can design the fallback UI using <a href=\"/docs/app/api-reference/file-conventions/loading\"><code>loading.js</code></a>:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/search/loading.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Loading</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;Loading...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>To cover cases when shared UI hasn't yet loaded, you can show instant feedback to the user using <a href=\"https://react.dev/reference/react-dom/hooks/useFormStatus\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>useFormStatus</code><span class=\"inline-flex not-prose\"></span></a>.</p><p>First, create a component that displays a loading state when the form is pending:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/ui/search-button.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useFormStatus } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react-dom'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> SearchButton</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> status</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> useFormStatus</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"submit\"</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-constant)\">status</span><span style=\"color:var(--shiki-color-text)\">.pending </span><span style=\"color:var(--shiki-token-keyword)\">?</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Searching...'</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Search'</span><span style=\"color:var(--shiki-color-text)\">}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Then, update the search form page to use the <code>SearchButton</code> component:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Form </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/form'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { SearchButton } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@/ui/search-button'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/search\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">input</span><span style=\"color:var(--shiki-token-function)\"> name</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"query\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">SearchButton</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><h3 id=\"mutations-with-server-actions\" data-docs-heading=\"\">Mutations with Server Actions<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#mutations-with-server-actions\"><span></span></a></h3><p>You can perform mutations by passing a function to the <code>action</code> prop.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/posts/create/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Form </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/form'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { createPost } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@/posts/actions'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{createPost}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">input</span><span style=\"color:var(--shiki-token-function)\"> name</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"title\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* ... */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"submit\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Create Post&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>After a mutation, it's common to redirect to the new resource. You can use the <a href=\"/docs/app/guides/redirecting\"><code>redirect</code></a> function from <code>next/navigation</code> to navigate to the new post page.</p><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Since the \"destination\" of the form submission is not known until the action is executed, <code>&lt;Form&gt;</code> cannot automatically prefetch shared UI.</p>\n</blockquote><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/posts/actions.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use server'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { redirect } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/navigation'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> createPost</span><span style=\"color:var(--shiki-color-text)\">(formData</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> FormData</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Create a new post</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // ...</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Redirect to the new post</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirect</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`/posts/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">data</span><span style=\"color:var(--shiki-color-text)\">.id</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Then, in the new page, you can fetch data using the <code>params</code> prop:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">/app/posts/[id]/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { getPost } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@/posts/data'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> PostPage</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;{ id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">id</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> params</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getPost</span><span style=\"color:var(--shiki-color-text)\">(id)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-constant)\">data</span><span style=\"color:var(--shiki-color-text)\">.title}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* ... */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>See <a href=\"/docs/app/getting-started/mutating-data\">Mutating data</a> for more examples.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components/image",
    "title": "Components: Image Component | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Image Component</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 4, 2026</div>\n<p>The Next.js Image component extends the HTML <code>&lt;img&gt;</code> element for automatic image optimization.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.png\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Picture of the author\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<h3 id=\"props\" data-docs-heading=\"\">Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#props\"><span></span></a></h3>\n<p>The following props are available:</p>\n<div style=\"overflow-x:auto;width:100%\"><div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Prop</th><th class=\"min-w-[12ch]\">Example</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Status</th></tr></thead><tbody><tr><td><a href=\"#src\"><code>src</code></a></td><td><code>src=\"/profile.png\"</code></td><td>String</td><td>Required</td></tr><tr><td><a href=\"#alt\"><code>alt</code></a></td><td><code>alt=\"Picture of the author\"</code></td><td>String</td><td>Required</td></tr><tr><td><a href=\"#width-and-height\"><code>width</code></a></td><td><code>width={500}</code></td><td>Integer (px)</td><td>-</td></tr><tr><td><a href=\"#width-and-height\"><code>height</code></a></td><td><code>height={500}</code></td><td>Integer (px)</td><td>-</td></tr><tr><td><a href=\"#fill\"><code>fill</code></a></td><td><code>fill={true}</code></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#loader\"><code>loader</code></a></td><td><code>loader={imageLoader}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#sizes\"><code>sizes</code></a></td><td><code>sizes=\"(max-width: 768px) 100vw, 33vw\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#quality\"><code>quality</code></a></td><td><code>quality={80}</code></td><td>Integer (1-100)</td><td>-</td></tr><tr><td><a href=\"#preload\"><code>preload</code></a></td><td><code>preload={true}</code></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#placeholder\"><code>placeholder</code></a></td><td><code>placeholder=\"blur\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#style\"><code>style</code></a></td><td><code>style={{objectFit: \"contain\"}}</code></td><td>Object</td><td>-</td></tr><tr><td><a href=\"#onloadingcomplete\"><code>onLoadingComplete</code></a></td><td><code>onLoadingComplete={img =&gt; done())}</code></td><td>Function</td><td>Deprecated</td></tr><tr><td><a href=\"#onload\"><code>onLoad</code></a></td><td><code>onLoad={event =&gt; done())}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#onerror\"><code>onError</code></a></td><td><code>onError(event =&gt; fail()}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#loading\"><code>loading</code></a></td><td><code>loading=\"lazy\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#blurdataurl\"><code>blurDataURL</code></a></td><td><code>blurDataURL=\"data:image/jpeg...\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#unoptimized\"><code>unoptimized</code></a></td><td><code>unoptimized={true}</code></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#overridesrc\"><code>overrideSrc</code></a></td><td><code>overrideSrc=\"/seo.png\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#decoding\"><code>decoding</code></a></td><td><code>decoding=\"async\"</code></td><td>String</td><td>-</td></tr></tbody></table></div></div>\n<h4 id=\"src\" data-docs-heading=\"\"><code>src</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#src\"><span></span></a></h4>\n<p>The source of the image. Can be one of the following:</p>\n<p>An internal path string.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.png\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<p>An absolute external URL (must be configured with <a href=\"#remotepatterns\">remotePatterns</a>).</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/profile.png\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<p>A static import.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> profile </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './profile.png'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{profile} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: For security reasons, the Image Optimization API using the default <a href=\"#loader\">loader</a> will <em>not</em> forward headers when fetching the <code>src</code> image.\nIf the <code>src</code> image requires authentication, consider using the <a href=\"#unoptimized\">unoptimized</a> property to disable Image Optimization.</p>\n</blockquote>\n<h4 id=\"alt\" data-docs-heading=\"\"><code>alt</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#alt\"><span></span></a></h4>\n<p>The <code>alt</code> property is used to describe the image for screen readers and search engines. It is also the fallback text if images have been disabled or an error occurs while loading the image.</p>\n<p>It should contain text that could replace the image <a href=\"https://html.spec.whatwg.org/multipage/images.html#general-guidelines\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">without changing the meaning of the page<span class=\"inline-flex not-prose\"></span></a>. It is not meant to supplement the image and should not repeat information that is already provided in the captions above or below the image.</p>\n<p>If the image is <a href=\"https://html.spec.whatwg.org/multipage/images.html#a-purely-decorative-image-that-doesn't-add-any-information\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">purely decorative<span class=\"inline-flex not-prose\"></span></a> or <a href=\"https://html.spec.whatwg.org/multipage/images.html#an-image-not-intended-for-the-user\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">not intended for the user<span class=\"inline-flex not-prose\"></span></a>, the <code>alt</code> property should be an empty string (<code>alt=\"\"</code>).</p>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about <a href=\"https://html.spec.whatwg.org/multipage/images.html#alt\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">image accessibility guidelines<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h4 id=\"width-and-height\" data-docs-heading=\"\"><code>width</code> and <code>height</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#width-and-height\"><span></span></a></h4>\n<p>The <code>width</code> and <code>height</code> properties represent the <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Intrinsic_Size\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">intrinsic<span class=\"inline-flex not-prose\"></span></a> image size in pixels. This property is used to infer the correct <strong>aspect ratio</strong> used by browsers to reserve space for the image and avoid layout shift during loading. It does not determine the <em>rendered size</em> of the image, which is controlled by CSS.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.png\"</span><span style=\"color:var(--shiki-token-function)\"> width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-function)\">height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span></code></pre></div>\n<p>You <strong>must</strong> set both <code>width</code> and <code>height</code> properties unless:</p>\n<ul>\n<li>The image is statically imported.</li>\n<li>The image has the <a href=\"#fill\"><code>fill</code> property</a></li>\n</ul>\n<p>If the height and width are unknown, we recommend using the <a href=\"#fill\"><code>fill</code> property</a>.</p>\n<h4 id=\"fill\" data-docs-heading=\"\"><code>fill</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#fill\"><span></span></a></h4>\n<p>A boolean that causes the image to expand to the size of the parent element.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.png\"</span><span style=\"color:var(--shiki-token-function)\"> fill</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">true</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span></code></pre></div>\n<p><strong>Positioning</strong>:</p>\n<ul>\n<li>The parent element <strong>must</strong> assign <code>position: \"relative\"</code>, <code>\"fixed\"</code>, <code>\"absolute\"</code>.</li>\n<li>By default, the <code>&lt;img&gt;</code> element uses <code>position: \"absolute\"</code>.</li>\n</ul>\n<p><strong>Object Fit</strong>:</p>\n<p>If no styles are applied to the image, the image will stretch to fit the container. You can use <code>objectFit</code> to control cropping and scaling.</p>\n<ul>\n<li><code>\"contain\"</code>: The image will be scaled down to fit the container and preserve aspect ratio.</li>\n<li><code>\"cover\"</code>: The image will fill the container and be cropped.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>position</code><span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://developer.mozilla.org/docs/Web/CSS/object-fit\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>object-fit</code><span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h4 id=\"loader\" data-docs-heading=\"\"><code>loader</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#loader\"><span></span></a></h4>\n<p>A custom function used to generate the image URL. The function receives the following parameters, and returns a URL string for the image:</p>\n<ul>\n<li><a href=\"#src\"><code>src</code></a></li>\n<li><a href=\"#width-and-height\"><code>width</code></a></li>\n<li><a href=\"#quality\"><code>quality</code></a></li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-function)\"> imageLoader</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> ({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?w=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">&amp;q=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      loader</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{imageLoader}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"me.png\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Picture of the author\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Using props like <code>onLoad</code>, which accept a function, requires using <a href=\"https://react.dev/reference/rsc/use-client\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Client Components<span class=\"inline-flex not-prose\"></span></a> to serialize the provided function.</p>\n</blockquote>\n<!-- -->\n<p>Alternatively, you can use the <a href=\"#loaderfile\">loaderFile</a> configuration in <code>next.config.js</code> to configure every instance of <code>next/image</code> in your application, without passing a prop.</p>\n<h4 id=\"sizes\" data-docs-heading=\"\"><code>sizes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#sizes\"><span></span></a></h4>\n<p>Define the sizes of the image at different breakpoints. Used by the browser to choose the most appropriate size from the generated <code>srcset</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"grid-element\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        fill</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/example.png\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        sizes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>sizes</code> should be used when:</p>\n<ul>\n<li>The image is using the <a href=\"#fill\"><code>fill</code></a> prop</li>\n<li>CSS is used to make the image responsive</li>\n</ul>\n<p>If <code>sizes</code> is missing, the browser assumes the image will be as wide as the viewport (<code>100vw</code>). This can cause unnecessarily large images to be downloaded.</p>\n<p>In addition, <code>sizes</code> affects how <code>srcset</code> is generated:</p>\n<ul>\n<li>Without <code>sizes</code>: Next.js generates a limited <code>srcset</code> (e.g. 1x, 2x), suitable for fixed-size images.</li>\n<li>With <code>sizes</code>: Next.js generates a full <code>srcset</code> (e.g. 640w, 750w, etc.), optimized for responsive layouts.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about <code>srcset</code> and <code>sizes</code> on <a href=\"https://web.dev/learn/design/responsive-images/#sizes\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">web.dev<span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://developer.mozilla.org/docs/Web/HTML/Element/img#sizes\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">mdn<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h4 id=\"quality\" data-docs-heading=\"\"><code>quality</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#quality\"><span></span></a></h4>\n<p>An integer between <code>1</code> and <code>100</code> that sets the quality of the optimized image. Higher values increase file size and visual fidelity. Lower values reduce file size but may affect sharpness.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Default quality is 75</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> quality</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">75</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span></code></pre></div>\n<p>If you’ve configured <a href=\"#qualities\">qualities</a> in <code>next.config.js</code>, the value must match one of the allowed entries.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If the original image is already low quality, setting a high quality value will increase the file size without improving appearance.</p>\n</blockquote>\n<h4 id=\"style\" data-docs-heading=\"\"><code>style</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#style\"><span></span></a></h4>\n<p>Allows passing CSS styles to the underlying image element.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> imageStyle</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  borderRadius</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '50%'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  border</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '1px solid #fff'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100px'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> ProfileImage</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"...\"</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{imageStyle} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you’re using the <code>style</code> prop to set a custom width, be sure to also set <code>height: 'auto'</code> to preserve the image’s aspect ratio.</p>\n</blockquote>\n<h4 id=\"preload\" data-docs-heading=\"\"><code>preload</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#preload\"><span></span></a></h4>\n<p>A boolean that indicates if the image should be preloaded.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Default preload is false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> preload</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span></code></pre></div>\n<ul>\n<li><code>true</code>: <a href=\"https://web.dev/preload-responsive-images/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Preloads<span class=\"inline-flex not-prose\"></span></a> the image by inserting a <code>&lt;link&gt;</code> in the <code>&lt;head&gt;</code>.</li>\n<li><code>false</code>: Does not preload the image.</li>\n</ul>\n<p><strong>When to use it:</strong></p>\n<ul>\n<li>The image is the <a href=\"https://nextjs.org/learn/seo/web-performance/lcp\" rel=\"noopener noreferrer\" target=\"_blank\">Largest Contentful Paint (LCP)<span class=\"inline-flex not-prose\"></span></a> element.</li>\n<li>The image is above the fold, typically the hero image.</li>\n<li>You want to begin loading the image in the <code>&lt;head&gt;</code>, before its discovered later in the <code>&lt;body&gt;</code>.</li>\n</ul>\n<p><strong>When not to use it:</strong></p>\n<ul>\n<li>When you have multiple images that could be considered the <a href=\"https://nextjs.org/learn/seo/web-performance/lcp\" rel=\"noopener noreferrer\" target=\"_blank\">Largest Contentful Paint (LCP)<span class=\"inline-flex not-prose\"></span></a> element depending on the viewport.</li>\n<li>When the <code>loading</code> property is used.</li>\n<li>When the <code>fetchPriority</code> property is used.</li>\n</ul>\n<p>In most cases, you should use <code>loading=\"eager\"</code> or <code>fetchPriority=\"high\"</code> instead of <code>preload</code>.</p>\n<h4 id=\"priority\" data-docs-heading=\"\"><code>priority</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#priority\"><span></span></a></h4>\n<p>Starting with Next.js 16, the <code>priority</code> property has been deprecated in favor of the <a href=\"#preload\"><code>preload</code></a> property in order to make the behavior clear.</p>\n<h4 id=\"loading\" data-docs-heading=\"\"><code>loading</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#loading\"><span></span></a></h4>\n<p>Controls when the image should start loading.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Defaults to lazy</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> loading</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"lazy\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<ul>\n<li><code>lazy</code>: Defer loading the image until it reaches a calculated distance from the viewport.</li>\n<li><code>eager</code>: Load the image immediately, regardless of its position in the page.</li>\n</ul>\n<p>Use <code>eager</code> only when you want to ensure the image is loaded immediately.</p>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about the <a href=\"https://developer.mozilla.org/docs/Web/HTML/Element/img#loading\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>loading</code> attribute<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h4 id=\"placeholder\" data-docs-heading=\"\"><code>placeholder</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#placeholder\"><span></span></a></h4>\n<p>Specifies a placeholder to use while the image is loading, improving the perceived loading performance.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// defaults to empty</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> placeholder</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"empty\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<ul>\n<li><code>empty</code>: No placeholder while the image is loading.</li>\n<li><code>blur</code>: Use a blurred version of the image as a placeholder. Must be used with the <a href=\"#blurdataurl\"><code>blurDataURL</code></a> property.</li>\n<li><code>data:image/...</code>: Uses the <a href=\"https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Data URL<span class=\"inline-flex not-prose\"></span></a> as the placeholder.</li>\n</ul>\n<p><strong>Examples:</strong></p>\n<ul>\n<li><a href=\"https://image-component.nextjs.gallery/placeholder\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>blur</code> placeholder<span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://image-component.nextjs.gallery/shimmer\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Shimmer effect with data URL <code>placeholder</code> prop<span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://image-component.nextjs.gallery/color\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Color effect with <code>blurDataURL</code> prop<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about the <a href=\"https://developer.mozilla.org/docs/Web/HTML/Element/img#placeholder\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>placeholder</code> attribute<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h4 id=\"blurdataurl\" data-docs-heading=\"\"><code>blurDataURL</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#blurdataurl\"><span></span></a></h4>\n<p>A <a href=\"https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Data URL<span class=\"inline-flex not-prose\"></span></a> to\nbe used as a placeholder image before the image successfully loads. Can be automatically set or used with the <a href=\"#placeholder\"><code>placeholder=\"blur\"</code></a> property.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> placeholder</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"blur\"</span><span style=\"color:var(--shiki-token-function)\"> blurDataURL</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"...\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<p>The image is automatically enlarged and blurred, so a very small image (10px or less) is recommended.</p>\n<p><strong>Automatic</strong></p>\n<p>If <code>src</code> is a static import of a <code>jpg</code>, <code>png</code>, <code>webp</code>, or <code>avif</code> file, <code>blurDataURL</code> is added automatically—unless the image is animated.</p>\n<p><strong>Manually set</strong></p>\n<p>If the image is dynamic or remote, you must provide <code>blurDataURL</code> yourself. To generate one, you can use:</p>\n<ul>\n<li><a href=\"https://png-pixel.com\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">A online tool like png-pixel.com<span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://github.com/joe-bell/plaiceholder\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">A library like Plaiceholder<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<p>A large blurDataURL may hurt performance. Keep it small and simple.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li><a href=\"https://image-component.nextjs.gallery/placeholder\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Default <code>blurDataURL</code> prop<span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://image-component.nextjs.gallery/color\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Color effect with <code>blurDataURL</code> prop<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h4 id=\"onload\" data-docs-heading=\"\"><code>onLoad</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onload\"><span></span></a></h4>\n<p>A callback function that is invoked once the image is completely loaded and the <a href=\"#placeholder\">placeholder</a> has been removed.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> onLoad</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">e</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">target</span><span style=\"color:var(--shiki-color-text)\">.naturalWidth)} /&gt;</span></span></code></pre></div>\n<p>The callback function will be called with one argument, the event which has a <code>target</code> that references the underlying <code>&lt;img&gt;</code> element.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Using props like <code>onLoad</code>, which accept a function, requires using <a href=\"https://react.dev/reference/rsc/use-client\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Client Components<span class=\"inline-flex not-prose\"></span></a> to serialize the provided function.</p>\n</blockquote>\n<h4 id=\"onerror\" data-docs-heading=\"\"><code>onError</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onerror\"><span></span></a></h4>\n<p>A callback function that is invoked if the image fails to load.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> onError</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> console</span><span style=\"color:var(--shiki-token-function)\">.error</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">e</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">target</span><span style=\"color:var(--shiki-color-text)\">.id)} /&gt;</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Using props like <code>onError</code>, which accept a function, requires using <a href=\"https://react.dev/reference/rsc/use-client\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Client Components<span class=\"inline-flex not-prose\"></span></a> to serialize the provided function.</p>\n</blockquote>\n<h4 id=\"unoptimized\" data-docs-heading=\"\"><code>unoptimized</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#unoptimized\"><span></span></a></h4>\n<p>A boolean that indicates if the image should be optimized. This is useful for images that do not benefit from optimization such as small images (less than 1KB), vector images (SVG), or animated images (GIF).</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-function)\"> UnoptimizedImage</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> (props) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Default is false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-color-text)\"> {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">props} </span><span style=\"color:var(--shiki-token-function)\">unoptimized</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<ul>\n<li><code>true</code>: The source image will be served as-is from the <code>src</code> instead of changing quality, size, or format.</li>\n<li><code>false</code>: The source image will be optimized.</li>\n</ul>\n<p>Since Next.js 12.3.0, this prop can be assigned to all images by updating <code>next.config.js</code> with the following configuration:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    unoptimized</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"overridesrc\" data-docs-heading=\"\"><code>overrideSrc</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#overridesrc\"><span></span></a></h4>\n<p>When providing the <code>src</code> prop to the <code>&lt;Image&gt;</code> component, both the <code>srcset</code> and <code>src</code> attributes are generated automatically for the resulting <code>&lt;img&gt;</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">input.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.jpg\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">output.html</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">img</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  srcset</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    /_next/image?url=%2Fprofile.jpg&amp;w=640&amp;q=75 1x,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    /_next/image?url=%2Fprofile.jpg&amp;w=828&amp;q=75 2x</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  \"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/_next/image?url=%2Fprofile.jpg&amp;w=828&amp;q=75\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">/&gt;</span></span></code></pre></div>\n<p>In some cases, it is not desirable to have the <code>src</code> attribute generated and you may wish to override it using the <code>overrideSrc</code> prop.</p>\n<p>For example, when upgrading an existing website from <code>&lt;img&gt;</code> to <code>&lt;Image&gt;</code>, you may wish to maintain the same <code>src</code> attribute for SEO purposes such as image ranking or avoiding recrawl.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">input.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/profile.jpg\"</span><span style=\"color:var(--shiki-token-function)\"> overrideSrc</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/override.jpg\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">output.html</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">img</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  srcset</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    /_next/image?url=%2Fprofile.jpg&amp;w=640&amp;q=75 1x,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    /_next/image?url=%2Fprofile.jpg&amp;w=828&amp;q=75 2x</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  \"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/override.jpg\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">/&gt;</span></span></code></pre></div>\n<h4 id=\"decoding\" data-docs-heading=\"\"><code>decoding</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#decoding\"><span></span></a></h4>\n<p>A hint to the browser indicating if it should wait for the image to be decoded before presenting other content updates or not.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Default is async</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> decoding</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"async\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<ul>\n<li><code>async</code>: Asynchronously decode the image and allow other content to be rendered before it completes.</li>\n<li><code>sync</code>: Synchronously decode the image for atomic presentation with other content.</li>\n<li><code>auto</code>: No preference. The browser chooses the best approach.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>Learn more about the <a href=\"https://developer.mozilla.org/docs/Web/HTML/Element/img#decoding\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>decoding</code> attribute<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<h3 id=\"other-props\" data-docs-heading=\"\">Other Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#other-props\"><span></span></a></h3>\n<p>Other properties on the <code>&lt;Image /&gt;</code> component will be passed to the underlying <code>img</code> element with the exception of the following:</p>\n<ul>\n<li><code>srcSet</code>: Use <a href=\"#devicesizes\">Device Sizes</a> instead.</li>\n</ul>\n<h3 id=\"deprecated-props\" data-docs-heading=\"\">Deprecated props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#deprecated-props\"><span></span></a></h3>\n<h4 id=\"onloadingcomplete\" data-docs-heading=\"\"><code>onLoadingComplete</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onloadingcomplete\"><span></span></a></h4>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning</strong>: Deprecated in Next.js 14, use <a href=\"#onload\"><code>onLoad</code></a> instead.</p>\n</blockquote>\n<p>A callback function that is invoked once the image is completely loaded and the <a href=\"#placeholder\">placeholder</a> has been removed.</p>\n<p>The callback function will be called with one argument, a reference to the underlying <code>&lt;img&gt;</code> element.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> onLoadingComplete</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(img) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">img</span><span style=\"color:var(--shiki-color-text)\">.naturalWidth)} /&gt;</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Using props like <code>onLoadingComplete</code>, which accept a function, requires using <a href=\"https://react.dev/reference/rsc/use-client\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Client Components<span class=\"inline-flex not-prose\"></span></a> to serialize the provided function.</p>\n</blockquote>\n<h3 id=\"configuration-options\" data-docs-heading=\"\">Configuration options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#configuration-options\"><span></span></a></h3>\n<p>You can configure the Image Component in <code>next.config.js</code>. The following options are available:</p>\n<h4 id=\"localpatterns\" data-docs-heading=\"\"><code>localPatterns</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#localpatterns\"><span></span></a></h4>\n<p>Use <code>localPatterns</code> in your <code>next.config.js</code> file to allow images from specific local paths to be optimized and block all others.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    localPatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        pathname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/assets/images/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        search</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The example above will ensure the <code>src</code> property of <code>next/image</code> must start with <code>/assets/images/</code> and must not have a query string. Attempting to optimize any other path will respond with <code>400</code> Bad Request error.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Omitting the <code>search</code> property allows all search parameters which could allow malicious actors to optimize URLs you did not intend. Try using a specific value like <code>search: '?v=2'</code> to ensure an exact match.</p>\n</blockquote>\n<h4 id=\"remotepatterns\" data-docs-heading=\"\"><code>remotePatterns</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#remotepatterns\"><span></span></a></h4>\n<p>Use <code>remotePatterns</code> in your <code>next.config.js</code> file to allow images from specific external paths and block all others. This ensures that only external images from your account can be served.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remotePatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-keyword)\">new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'https://example.com/account123/**'</span><span style=\"color:var(--shiki-color-text)\">)]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also configure <code>remotePatterns</code> using the object:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remotePatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        protocol</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        hostname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        port</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        pathname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/account123/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        search</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The example above will ensure the <code>src</code> property of <code>next/image</code> must start with <code>https://example.com/account123/</code> and must not have a query string. Any other protocol, hostname, port, or unmatched path will respond with <code>400</code> Bad Request.</p>\n<p><strong>Wildcard Patterns:</strong></p>\n<p>Wildcard patterns can be used for both <code>pathname</code> and <code>hostname</code> and have the following syntax:</p>\n<ul>\n<li><code>*</code> match a single path segment or subdomain</li>\n<li><code>**</code> match any number of path segments at the end or subdomains at the beginning. This syntax does not work in the middle of the pattern.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remotePatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        protocol</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        hostname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**.example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        port</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        search</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This allows subdomains like <code>image.example.com</code>. Query strings and custom ports are still blocked.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: When omitting <code>protocol</code>, <code>port</code>, <code>pathname</code>, or <code>search</code> then the wildcard <code>**</code> is implied. This is not recommended because it may allow malicious actors to optimize urls you did not intend.</p>\n</blockquote>\n<p><strong>Query Strings</strong>:</p>\n<p>You can also restrict query strings using the <code>search</code> property:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remotePatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        protocol</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        hostname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'assets.example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        search</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '?v=1727111025337'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The example above will ensure the <code>src</code> property of <code>next/image</code> must start with <code>https://assets.example.com</code> and must have the exact query string <code>?v=1727111025337</code>. Any other protocol or query string will respond with <code>400</code> Bad Request.</p>\n<p>Note that any allowed <code>remotePatterns</code> that respond with a redirect will follow the redirect from the remote image server without validating <code>remotePatterns</code> again on the redirect location. You can reduce or disable redirects by configuring <a href=\"#maximumredirects\">maximumRedirects</a>.</p>\n<h4 id=\"loaderfile\" data-docs-heading=\"\"><code>loaderFile</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#loaderfile\"><span></span></a></h4>\n<p><code>loaderFiles</code> allows you to use a custom image optimization service instead of Next.js.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    loader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'custom'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    loaderFile</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './my/image/loader.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The path must be relative to the project root. The file must export a default function that returns a URL string:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my/image/loader.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> myImageLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?w=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">&amp;q=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p><strong>Example:</strong></p>\n<ul>\n<li><a href=\"/docs/app/api-reference/config/next-config-js/images#example-loader-configuration\">Custom Image Loader Configuration</a></li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>Alternatively, you can use the <a href=\"#loader\"><code>loader</code> prop</a> to configure each instance of <code>next/image</code>.</p>\n</blockquote>\n<h4 id=\"path\" data-docs-heading=\"\"><code>path</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#path\"><span></span></a></h4>\n<p>If you want to change or prefix the default path for the Image Optimization API, you can do so with the <code>path</code> property. The default value for <code>path</code> is <code>/_next/image</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/my-prefix/_next/image'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"devicesizes\" data-docs-heading=\"\"><code>deviceSizes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#devicesizes\"><span></span></a></h4>\n<p><code>deviceSizes</code> allows you to specify a list of device width breakpoints. These widths are used when the <code>next/image</code> component uses <a href=\"#sizes\"><code>sizes</code></a> prop to ensure the correct image is served for the user's device.</p>\n<p>If no configuration is provided, the default below is used:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    deviceSizes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">640</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 750</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 828</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 1080</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 1200</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 1920</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 2048</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 3840</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"imagesizes\" data-docs-heading=\"\"><code>imageSizes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#imagesizes\"><span></span></a></h4>\n<p><code>imageSizes</code> allows you to specify a list of image widths. These widths are concatenated with the array of <a href=\"#devicesizes\">device sizes</a> to form the full array of sizes used to generate image <a href=\"https://developer.mozilla.org/docs/Web/API/HTMLImageElement/srcset\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">srcset<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>If no configuration is provided, the default below is used:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    imageSizes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">32</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 48</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 64</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 96</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 128</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 256</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 384</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>imageSizes</code> is only used for images which provide a <a href=\"#sizes\"><code>sizes</code></a> prop, which indicates that the image is less than the full width of the screen. Therefore, the sizes in <code>imageSizes</code> should all be smaller than the smallest size in <code>deviceSizes</code>.</p>\n<h4 id=\"qualities\" data-docs-heading=\"\"><code>qualities</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#qualities\"><span></span></a></h4>\n<p><code>qualities</code> allows you to specify a list of image quality values.</p>\n<p>If not configuration is provided, the default below is used:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    qualities</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">75</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This field is required starting with Next.js 16 because unrestricted access could allow malicious actors to optimize more qualities than you intended.</p>\n</blockquote>\n<p>You can add more image qualities to the allowlist, such as the following:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    qualities</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">25</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 50</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 100</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>In the example above, only four qualities are allowed: 25, 50, 75, and 100.</p>\n<p>If the <a href=\"#quality\"><code>quality</code></a> prop does not match a value in this array, the closest allowed value will be used.</p>\n<p>If the REST API is visited directly with a quality that does not match a value in this array, the server will return a 400 Bad Request response.</p>\n<h4 id=\"formats\" data-docs-heading=\"\"><code>formats</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#formats\"><span></span></a></h4>\n<p><code>formats</code> allows you to specify a list of image formats to be used.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    formats</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'image/webp'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Next.js automatically detects the browser's supported image formats via the request's <code>Accept</code> header in order to determine the best output format.</p>\n<p>If the <code>Accept</code> header matches more than one of the configured formats, the first match in the array is used. Therefore, the array order matters. If there is no match (or the source image is animated), it will use the original image's format.</p>\n<p>You can enable AVIF support, which will fallback to the original format of the src image if the browser <a href=\"https://caniuse.com/avif\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">does not support AVIF<span class=\"inline-flex not-prose\"></span></a>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    formats</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'image/avif'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also enable both AVIF and WebP formats together. AVIF will be preferred for browsers that support it, with WebP as a fallback:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    formats</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'image/avif'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'image/webp'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>We still recommend using WebP for most use cases.</li>\n<li>AVIF generally takes 50% longer to encode but it compresses 20% smaller compared to WebP. This means that the first time an image is requested, it will typically be slower, but subsequent requests that are cached will be faster.</li>\n<li>When using multiple formats, Next.js will cache each format separately. This means increased storage requirements compared to using a single format, as both AVIF and WebP versions of images will be stored for different browser support.</li>\n<li>If you self-host with a Proxy/CDN in front of Next.js, you must configure the Proxy to forward the <code>Accept</code> header.</li>\n</ul>\n</blockquote>\n<h4 id=\"minimumcachettl\" data-docs-heading=\"\"><code>minimumCacheTTL</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#minimumcachettl\"><span></span></a></h4>\n<p><code>minimumCacheTTL</code> allows you to configure the Time to Live (TTL) in seconds for cached optimized images. In many cases, it's better to use a <a href=\"/docs/app/getting-started/images#local-images\">Static Image Import</a> which will automatically hash the file contents and cache the image forever with a <code>Cache-Control</code> header of <code>immutable</code>.</p>\n<p>If no configuration is provided, the default below is used.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    minimumCacheTTL</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 14400</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 4 hours</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can increase the TTL to reduce the number of revalidations and potentially lower cost:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    minimumCacheTTL</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 2678400</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 31 days</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The expiration (or rather Max Age) of the optimized image is defined by either the <code>minimumCacheTTL</code> or the upstream image <code>Cache-Control</code> header, whichever is larger.</p>\n<p>If you need to change the caching behavior per image, you can configure <a href=\"/docs/app/api-reference/config/next-config-js/headers\"><code>headers</code></a> to set the <code>Cache-Control</code> header on the upstream image (e.g. <code>/some-asset.jpg</code>, not <code>/_next/image</code> itself).</p>\n<p>There is no mechanism to invalidate the cache at this time, so its best to keep <code>minimumCacheTTL</code> low. Otherwise you may need to manually change the <a href=\"#src\"><code>src</code></a> prop or delete the cached file <code>&lt;distDir&gt;/cache/images</code>.</p>\n<h4 id=\"disablestaticimages\" data-docs-heading=\"\"><code>disableStaticImages</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disablestaticimages\"><span></span></a></h4>\n<p><code>disableStaticImages</code> allows you to disable static image imports.</p>\n<p>The default behavior allows you to import static files such as <code>import icon from './icon.png'</code> and then pass that to the <code>src</code> property. In some cases, you may wish to disable this feature if it conflicts with other plugins that expect the import to behave differently.</p>\n<p>You can disable static image imports inside your <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    disableStaticImages</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"maximumredirects\" data-docs-heading=\"\"><code>maximumRedirects</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#maximumredirects\"><span></span></a></h4>\n<p>The default image optimization loader will follow HTTP redirects when fetching remote images up to 3 times.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumRedirects</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 3</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>For your convenience, these redirects do not need to satisfy <a href=\"#remotepatterns\">remotePatterns</a>.</p>\n<p>You can configure the number of redirects to follow when fetching remote images. Setting the value to <code>0</code> will disable following redirects.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumRedirects</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"maximumdiskcachesize\" data-docs-heading=\"\"><code>maximumDiskCacheSize</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#maximumdiskcachesize\"><span></span></a></h4>\n<p>The default image optimization loader will write optimized images to disk so subsequent requests can be served faster from the disk cache.</p>\n<p>You can configure the maximum disk cache size in bytes, for example 500 MB:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumDiskCacheSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 500_000_000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also disable the disk cache entirely by setting the value to <code>0</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumDiskCacheSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If no value is configured, the default behavior is to check the current available disk space once during startup and use 50%.</p>\n<p>When the disk cache exceeds the configured size, the least recently used optimized images will be deleted until the cache is under the limit again.</p>\n<p>Alternatively, you can implement your own cache handler using <a href=\"/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath\"><code>cacheHandler</code></a> which will ignore the <code>maximumDiskCacheSize</code> configuration.</p>\n<h4 id=\"maximumresponsebody\" data-docs-heading=\"\"><code>maximumResponseBody</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#maximumresponsebody\"><span></span></a></h4>\n<p>The default image optimization loader will fetch source images up to 50 MB in size.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumResponseBody</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 50_000_000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If you know all your source images are small, you can protect memory constrained servers by reducing this to a smaller value such as 5 MB.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maximumResponseBody</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 5_000_000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"dangerouslyallowlocalip\" data-docs-heading=\"\"><code>dangerouslyAllowLocalIP</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#dangerouslyallowlocalip\"><span></span></a></h4>\n<p>In rare cases when self-hosting Next.js on a private network, you may want to allow optimizing images from local IP addresses on the same network. This is not recommended for most users because it could allow malicious users to access content on your internal network.</p>\n<p>By default, the value is false.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    dangerouslyAllowLocalIP</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If you need to optimize remote images hosted elsewhere in your local network, you can set the value to true.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    dangerouslyAllowLocalIP</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This might be necessary when hosting Next.js in a VPC with split-horizon DNS and you receive status 400 Bad Request. Only enable once you understand the SSRF risk.</p>\n<h4 id=\"dangerouslyallowsvg\" data-docs-heading=\"\"><code>dangerouslyAllowSVG</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#dangerouslyallowsvg\"><span></span></a></h4>\n<p><code>dangerouslyAllowSVG</code> allows you to serve SVG images.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    dangerouslyAllowSVG</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>By default, Next.js does not optimize SVG images for a few reasons:</p>\n<ul>\n<li>SVG is a vector format meaning it can be resized losslessly.</li>\n<li>SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without proper <a href=\"/docs/app/api-reference/config/next-config-js/headers#content-security-policy\">Content Security Policy (CSP) headers</a>.</li>\n</ul>\n<p>We recommend using the <a href=\"#unoptimized\"><code>unoptimized</code></a> prop when the <a href=\"#src\"><code>src</code></a> prop is known to be SVG. This happens automatically when <code>src</code> ends with <code>\".svg\"</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/my-image.svg\"</span><span style=\"color:var(--shiki-token-function)\"> unoptimized</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span></code></pre></div>\n<p>In addition, it is strongly recommended to also set <code>contentDispositionType</code> to force the browser to download the image, as well as <code>contentSecurityPolicy</code> to prevent scripts embedded in the image from executing.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    dangerouslyAllowSVG</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    contentDispositionType</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'attachment'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    contentSecurityPolicy</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"default-src 'self'; script-src 'none'; sandbox;\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"contentdispositiontype\" data-docs-heading=\"\"><code>contentDispositionType</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#contentdispositiontype\"><span></span></a></h4>\n<p><code>contentDispositionType</code> allows you to configure the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_response_header_for_the_main_body\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Content-Disposition</code><span class=\"inline-flex not-prose\"></span></a> header.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    contentDispositionType</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'inline'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"contentsecuritypolicy\" data-docs-heading=\"\"><code>contentSecurityPolicy</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#contentsecuritypolicy\"><span></span></a></h4>\n<p><code>contentSecurityPolicy</code> allows you to configure the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Content-Security-Policy</code><span class=\"inline-flex not-prose\"></span></a> header for images. This is particularly important when using <a href=\"#dangerouslyallowsvg\"><code>dangerouslyAllowSVG</code></a> to prevent scripts embedded in the image from executing.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    contentSecurityPolicy</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"default-src 'self'; script-src 'none'; sandbox;\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>By default, the <a href=\"#loader\">loader</a> sets the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_response_header_for_the_main_body\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Content-Disposition</code><span class=\"inline-flex not-prose\"></span></a> header to <code>attachment</code> for added protection since the API can serve arbitrary remote images.</p>\n<p>The default value is <code>attachment</code> which forces the browser to download the image when visiting directly. This is particularly important when <a href=\"#dangerouslyallowsvg\"><code>dangerouslyAllowSVG</code></a> is true.</p>\n<p>You can optionally configure <code>inline</code> to allow the browser to render the image when visiting directly, without downloading it.</p>\n<h3 id=\"deprecated-configuration-options\" data-docs-heading=\"\">Deprecated configuration options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#deprecated-configuration-options\"><span></span></a></h3>\n<h4 id=\"domains\" data-docs-heading=\"\"><code>domains</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#domains\"><span></span></a></h4>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning</strong>: Deprecated since Next.js 14 in favor of strict <a href=\"#remotepatterns\"><code>remotePatterns</code></a> in order to protect your application from malicious users.</p>\n</blockquote>\n<p>Similar to <a href=\"#remotepatterns\"><code>remotePatterns</code></a>, the <code>domains</code> configuration can be used to provide a list of allowed hostnames for external images. However, the <code>domains</code> configuration does not support wildcard pattern matching and it cannot restrict protocol, port, or pathname.</p>\n<p>Since most remote image servers are shared between multiple tenants, it's safer to use <code>remotePatterns</code> to ensure only the intended images are optimized.</p>\n<p>Below is an example of the <code>domains</code> property in the <code>next.config.js</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    domains</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'assets.acme.com'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"functions\" data-docs-heading=\"\">Functions<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#functions\"><span></span></a></h2>\n<h3 id=\"getimageprops\" data-docs-heading=\"\"><code>getImageProps</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#getimageprops\"><span></span></a></h3>\n<p>The <code>getImageProps</code> function can be used to get the props that would be passed to the underlying <code>&lt;img&gt;</code> element, and instead pass them to another component, style, canvas, etc.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { getImageProps } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">props</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> getImageProps</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/image.jpg'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  alt</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'A scenic mountain view'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1200</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 800</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> ImageWithCaption</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">figure</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">img</span><span style=\"color:var(--shiki-color-text)\"> {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">props} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">figcaption</span><span style=\"color:var(--shiki-color-text)\">&gt;A scenic mountain view&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">figcaption</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">figure</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This also avoid calling React <code>useState()</code> so it can lead to better performance, but it cannot be used with the <a href=\"#placeholder\"><code>placeholder</code></a> prop because the placeholder will never be removed.</p>\n<h2 id=\"known-browser-bugs\" data-docs-heading=\"\">Known browser bugs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#known-browser-bugs\"><span></span></a></h2>\n<p>This <code>next/image</code> component uses browser native <a href=\"https://caniuse.com/loading-lazy-attr\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">lazy loading<span class=\"inline-flex not-prose\"></span></a>, which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with <code>width</code>/<code>height</code> of <code>auto</code>, it is possible to cause <a href=\"https://web.dev/cls/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Layout Shift<span class=\"inline-flex not-prose\"></span></a> on older browsers before Safari 15 that don't <a href=\"https://caniuse.com/mdn-html_elements_img_aspect_ratio_computed_from_attributes\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">preserve the aspect ratio<span class=\"inline-flex not-prose\"></span></a>. For more details, see <a href=\"https://www.youtube.com/watch?v=4-d_SoCHeWE\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">this MDN video<span class=\"inline-flex not-prose\"></span></a>.</p>\n<ul>\n<li><a href=\"https://bugs.webkit.org/show_bug.cgi?id=243601\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Safari 15 - 16.3<span class=\"inline-flex not-prose\"></span></a> display a gray border while loading. Safari 16.4 <a href=\"https://webkit.org/blog/13966/webkit-features-in-safari-16-4/#:~:text=Now%20in%20Safari%2016.4%2C%20a%20gray%20line%20no%20longer%20appears%20to%20mark%20the%20space%20where%20a%20lazy%2Dloaded%20image%20will%20appear%20once%20it%E2%80%99s%20been%20loaded.\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">fixed this issue<span class=\"inline-flex not-prose\"></span></a>. Possible solutions:<!-- -->\n<ul>\n<li>Use CSS <code>@supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading=\"lazy\"] { clip-path: inset(0.6px) } }</code></li>\n<li>Use <a href=\"#loading\"><code>loading=\"eager\"</code></a> if the image is above the fold</li>\n</ul>\n</li>\n<li><a href=\"https://bugzilla.mozilla.org/show_bug.cgi?id=1556156\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Firefox 67+<span class=\"inline-flex not-prose\"></span></a> displays a white background while loading. Possible solutions:<!-- -->\n<ul>\n<li>Enable <a href=\"#formats\">AVIF <code>formats</code></a></li>\n<li>Use <a href=\"#placeholder\"><code>placeholder</code></a></li>\n</ul>\n</li>\n</ul>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"styling-images\" data-docs-heading=\"\">Styling images<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#styling-images\"><span></span></a></h3>\n<p>Styling the Image component is similar to styling a normal <code>&lt;img&gt;</code> element, but there are a few guidelines to keep in mind:</p>\n<p>Use <code>className</code> or <code>style</code>, not <code>styled-jsx</code>. In most cases, we recommend using the <code>className</code> prop. This can be an imported <a href=\"/docs/app/getting-started/css\">CSS Module</a>, a <a href=\"/docs/app/getting-started/css#global-css\">global stylesheet</a>, etc.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> styles </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './styles.module.css'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> MyImage</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">styles</span><span style=\"color:var(--shiki-color-text)\">.image} </span><span style=\"color:var(--shiki-token-function)\">src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/my-image.png\"</span><span style=\"color:var(--shiki-token-function)\"> alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"My Image\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also use the <code>style</code> prop to assign inline styles.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> MyImage</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ borderRadius</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '8px'</span><span style=\"color:var(--shiki-color-text)\"> }} </span><span style=\"color:var(--shiki-token-function)\">src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/my-image.png\"</span><span style=\"color:var(--shiki-token-function)\"> alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"My Image\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>When using <code>fill</code>, the parent element must have <code>position: relative</code> or <code>display: block</code>. This is necessary for the proper rendering of the image element in that layout mode.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ position</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'relative'</span><span style=\"color:var(--shiki-color-text)\"> }}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> fill</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/my-image.png\"</span><span style=\"color:var(--shiki-token-function)\"> alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"My Image\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<p>You cannot use <a href=\"/docs/app/guides/css-in-js\">styled-jsx</a> because it's scoped to the current component (unless you mark the style as <code>global</code>).</p>\n<h3 id=\"responsive-images-with-a-static-export\" data-docs-heading=\"\">Responsive images with a static export<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#responsive-images-with-a-static-export\"><span></span></a></h3>\n<p>When you import a static image, Next.js automatically sets its width and height based on the file. You can make the image responsive by setting the style:</p>\n<figure><img alt=\"Responsive image filling the width and height of its parent container\" loading=\"lazy\" width=\"1600\" height=\"629\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 dark-theme:hidden\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fresponsive-image.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fresponsive-image.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fresponsive-image.png&amp;w=3840&amp;q=75\"><img alt=\"Responsive image filling the width and height of its parent container\" loading=\"lazy\" width=\"1600\" height=\"629\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 hidden dark-theme:block\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fresponsive-image.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fresponsive-image.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fresponsive-image.png&amp;w=3840&amp;q=75\"></figure>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> mountains </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../public/mountains.jpg'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Responsive</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'flex'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> flexDirection</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'column'</span><span style=\"color:var(--shiki-color-text)\"> }}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Mountains\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Importing an image will</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // automatically set the width and height</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{mountains}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        sizes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"100vw\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Make the image display full width</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // and preserve its aspect ratio</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100%'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"responsive-images-with-a-remote-url\" data-docs-heading=\"\">Responsive images with a remote URL<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#responsive-images-with-a-remote-url\"><span></span></a></h3>\n<p>If the source image is a dynamic or a remote URL, you must provide the width and height props so Next.js can calculate the aspect ratio:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">components/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">({ photoUrl }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{photoUrl}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Picture of the author\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      sizes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"100vw\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100%'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">300</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Try it out:</p>\n<ul>\n<li><a href=\"https://image-component.nextjs.gallery/responsive\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Demo the image responsive to viewport<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h3 id=\"responsive-image-with-fill\" data-docs-heading=\"\">Responsive image with <code>fill</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#responsive-image-with-fill\"><span></span></a></h3>\n<p>If you don't know the aspect ratio of the image, you can add the <a href=\"#fill\"><code>fill</code> prop</a> with the <code>objectFit</code> prop set to <code>cover</code>. This will make the image fill the full width of its parent container.</p>\n<figure><img alt=\"Grid of images filling parent container width\" loading=\"lazy\" width=\"1600\" height=\"529\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 dark-theme:hidden\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ffill-container.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ffill-container.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ffill-container.png&amp;w=3840&amp;q=75\"><img alt=\"Grid of images filling parent container width\" loading=\"lazy\" width=\"1600\" height=\"529\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 hidden dark-theme:block\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ffill-container.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ffill-container.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ffill-container.png&amp;w=3840&amp;q=75\"></figure>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> mountains </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../public/mountains.jpg'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Fill</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'grid'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        gridGap</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '8px'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        gridTemplateColumns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'repeat(auto-fit, minmax(400px, auto))'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ position</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'relative'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '400px'</span><span style=\"color:var(--shiki-color-text)\"> }}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Mountains\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{mountains}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          fill</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          sizes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"(min-width: 808px) 50vw, 100vw\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            objectFit</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'cover'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // cover, contain, none</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* And more images in the grid... */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"background-image\" data-docs-heading=\"\">Background Image<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#background-image\"><span></span></a></h3>\n<p>Use the <code>fill</code> prop to make the image cover the entire screen area:</p>\n<figure><img alt=\"Background image taking full width and height of page\" loading=\"lazy\" width=\"1600\" height=\"427\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 dark-theme:hidden\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fbackground-image.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fbackground-image.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Fbackground-image.png&amp;w=3840&amp;q=75\"><img alt=\"Background image taking full width and height of page\" loading=\"lazy\" width=\"1600\" height=\"427\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 hidden dark-theme:block\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fbackground-image.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fbackground-image.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Fbackground-image.png&amp;w=3840&amp;q=75\"></figure>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> mountains </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../public/mountains.jpg'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Background</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Mountains\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{mountains}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      placeholder</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"blur\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      quality</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">100</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      fill</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      sizes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"100vw\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        objectFit</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'cover'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>For examples of the Image component used with the various styles, see the <a href=\"https://image-component.nextjs.gallery\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Image Component Demo<span class=\"inline-flex not-prose\"></span></a>.</p>\n<h3 id=\"remote-images\" data-docs-heading=\"\">Remote images<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#remote-images\"><span></span></a></h3>\n<p>To use a remote image, the <code>src</code> property should be a URL string.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://s3.amazonaws.com/my-bucket/profile.png\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Picture of the author\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Since Next.js does not have access to remote files during the build process, you'll need to provide the <a href=\"/docs/app/api-reference/components/image#width-and-height\"><code>width</code></a>, <a href=\"/docs/app/api-reference/components/image#width-and-height\"><code>height</code></a> and optional <a href=\"/docs/app/api-reference/components/image#blurdataurl\"><code>blurDataURL</code></a> props manually.</p>\n<p>The <code>width</code> and <code>height</code> attributes are used to infer the correct aspect ratio of image and avoid layout shift from the image loading in. The <code>width</code> and <code>height</code> do <em>not</em> determine the rendered size of the image file.</p>\n<p>To safely allow optimizing images, define a list of supported URL patterns in <code>next.config.js</code>. Be as specific as possible to prevent malicious usage. For example, the following configuration will only allow images from a specific AWS S3 bucket:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remotePatterns</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        protocol</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        hostname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 's3.amazonaws.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        port</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        pathname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/my-bucket/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        search</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"theme-detection\" data-docs-heading=\"\">Theme detection<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#theme-detection\"><span></span></a></h3>\n<p>If you want to display a different image for light and dark mode, you can create a new component that wraps two <code>&lt;Image&gt;</code> components and reveals the correct one based on a CSS media query.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">components/theme-image.module.css</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">.imgDark</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> none</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">@media</span><span style=\"color:var(--shiki-color-text)\"> (prefers-color-scheme</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> dark) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  .imgLight</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> none</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  .imgDark</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    display</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> unset</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">components/theme-image.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> styles </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './theme-image.module.css'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { ImageProps } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">type</span><span style=\"color:var(--shiki-token-function)\"> Props</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> Omit</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">ImageProps</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'src'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'preload'</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-string-expression)\"> 'loading'</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-keyword)\">&amp;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  srcLight</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  srcDark</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-function)\"> ThemeImage</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> (props</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Props</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">srcLight</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> srcDark</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-keyword)\"> ...</span><span style=\"color:var(--shiki-token-constant)\">rest</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\"> props</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-color-text)\"> {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">rest} </span><span style=\"color:var(--shiki-token-function)\">src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{srcLight} </span><span style=\"color:var(--shiki-token-function)\">className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">styles</span><span style=\"color:var(--shiki-color-text)\">.imgLight} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-color-text)\"> {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">rest} </span><span style=\"color:var(--shiki-token-function)\">src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{srcDark} </span><span style=\"color:var(--shiki-token-function)\">className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">styles</span><span style=\"color:var(--shiki-color-text)\">.imgDark} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: The default behavior of <code>loading=\"lazy\"</code> ensures that only the correct image is loaded. You cannot use <code>preload</code> or <code>loading=\"eager\"</code> because that would cause both images to load. Instead, you can use <a href=\"https://developer.mozilla.org/docs/Web/API/HTMLImageElement/fetchPriority\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>fetchPriority=\"high\"</code><span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<p>Try it out:</p>\n<ul>\n<li><a href=\"https://image-component.nextjs.gallery/theme\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Demo light/dark mode theme detection<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h3 id=\"art-direction\" data-docs-heading=\"\">Art direction<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#art-direction\"><span></span></a></h3>\n<p>If you want to display a different image for mobile and desktop, sometimes called <a href=\"https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#art_direction\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Art Direction<span class=\"inline-flex not-prose\"></span></a>, you can provide different <code>src</code>, <code>width</code>, <code>height</code>, and <code>quality</code> props to <code>getImageProps()</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { getImageProps } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Home</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> common</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> { alt</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Art Direction Example'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sizes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100vw'</span><span style=\"color:var(--shiki-color-text)\"> }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    props: { srcSet: </span><span style=\"color:var(--shiki-token-constant)\">desktop</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> getImageProps</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    ...</span><span style=\"color:var(--shiki-color-text)\">common</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1440</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 875</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    quality</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 80</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/desktop.jpg'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    props: { srcSet: </span><span style=\"color:var(--shiki-token-constant)\">mobile</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-keyword)\"> ...</span><span style=\"color:var(--shiki-token-constant)\">rest</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> getImageProps</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    ...</span><span style=\"color:var(--shiki-color-text)\">common</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 750</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1334</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    quality</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 70</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/mobile.jpg'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  })</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">picture</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">source</span><span style=\"color:var(--shiki-token-function)\"> media</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"(min-width: 1000px)\"</span><span style=\"color:var(--shiki-token-function)\"> srcSet</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{desktop} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">source</span><span style=\"color:var(--shiki-token-function)\"> media</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"(min-width: 500px)\"</span><span style=\"color:var(--shiki-token-function)\"> srcSet</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{mobile} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">img</span><span style=\"color:var(--shiki-color-text)\"> {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">rest} </span><span style=\"color:var(--shiki-token-function)\">style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100%'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-color-text)\"> }} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">picture</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"background-css\" data-docs-heading=\"\">Background CSS<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#background-css\"><span></span></a></h3>\n<p>You can even convert the <code>srcSet</code> string to the <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>image-set()</code><span class=\"inline-flex not-prose\"></span></a> CSS function to optimize a background image.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { getImageProps } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> getBackgroundImage</span><span style=\"color:var(--shiki-color-text)\">(srcSet </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> imageSet</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> srcSet</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    .split</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">', '</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    .map</span><span style=\"color:var(--shiki-color-text)\">((str) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      const</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">url</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> dpi</span><span style=\"color:var(--shiki-color-text)\">] </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-constant)\"> str</span><span style=\"color:var(--shiki-token-function)\">.split</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">' '</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-string-expression)\"> `url(\"</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">url</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">\") </span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">dpi</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    .join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">', '</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `image-set(</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">imageSet</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">)`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Home</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    props: { </span><span style=\"color:var(--shiki-token-constant)\">srcSet</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> getImageProps</span><span style=\"color:var(--shiki-color-text)\">({ alt</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 128</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 128</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/img.png'</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> backgroundImage</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> getBackgroundImage</span><span style=\"color:var(--shiki-color-text)\">(srcSet)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> style</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> { height</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100vh'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '100vw'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> backgroundImage }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-token-function)\"> style</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{style}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;Hello World&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.1.7</code></td><td><code>maximumDiskCacheSize</code> configuration added.</td></tr><tr><td><code>v16.1.2</code></td><td><code>maximumResponseBody</code> configuration added.</td></tr><tr><td><code>v16.0.0</code></td><td><code>qualities</code> default configuration changed to <code>[75]</code>, <code>preload</code> prop added, <code>priority</code> prop deprecated, <code>dangerouslyAllowLocalIP</code> config added, <code>maximumRedirects</code> config added.</td></tr><tr><td><code>v15.3.0</code></td><td><code>remotePatterns</code> added support for array of <code>URL</code> objects.</td></tr><tr><td><code>v15.0.0</code></td><td><code>contentDispositionType</code> configuration default changed to <code>attachment</code>.</td></tr><tr><td><code>v14.2.23</code></td><td><code>qualities</code> configuration added.</td></tr><tr><td><code>v14.2.15</code></td><td><code>decoding</code> prop added and <code>localPatterns</code> configuration added.</td></tr><tr><td><code>v14.2.14</code></td><td><code>remotePatterns.search</code> prop added.</td></tr><tr><td><code>v14.2.0</code></td><td><code>overrideSrc</code> prop added.</td></tr><tr><td><code>v14.1.0</code></td><td><code>getImageProps()</code> is stable.</td></tr><tr><td><code>v14.0.0</code></td><td><code>onLoadingComplete</code> prop and <code>domains</code> config deprecated.</td></tr><tr><td><code>v13.4.14</code></td><td><code>placeholder</code> prop support for <code>data:/image...</code></td></tr><tr><td><code>v13.2.0</code></td><td><code>contentDispositionType</code> configuration added.</td></tr><tr><td><code>v13.0.6</code></td><td><code>ref</code> prop added.</td></tr><tr><td><code>v13.0.0</code></td><td>The <code>next/image</code> import was renamed to <code>next/legacy/image</code>. The <code>next/future/image</code> import was renamed to <code>next/image</code>. A <a href=\"/docs/app/guides/upgrading/codemods#next-image-to-legacy-image\">codemod is available</a> to safely and automatically rename your imports. <code>&lt;span&gt;</code> wrapper removed. <code>layout</code>, <code>objectFit</code>, <code>objectPosition</code>, <code>lazyBoundary</code>, <code>lazyRoot</code> props removed. <code>alt</code> is required. <code>onLoadingComplete</code> receives reference to <code>img</code> element. Built-in loader config removed.</td></tr><tr><td><code>v12.3.0</code></td><td><code>remotePatterns</code> and <code>unoptimized</code> configuration is stable.</td></tr><tr><td><code>v12.2.0</code></td><td>Experimental <code>remotePatterns</code> and experimental <code>unoptimized</code> configuration added. <code>layout=\"raw\"</code> removed.</td></tr><tr><td><code>v12.1.1</code></td><td><code>style</code> prop added. Experimental support for <code>layout=\"raw\"</code> added.</td></tr><tr><td><code>v12.1.0</code></td><td><code>dangerouslyAllowSVG</code> and <code>contentSecurityPolicy</code> configuration added.</td></tr><tr><td><code>v12.0.9</code></td><td><code>lazyRoot</code> prop added.</td></tr><tr><td><code>v12.0.0</code></td><td><code>formats</code> configuration added.<br>AVIF support added.<br>Wrapper <code>&lt;div&gt;</code> changed to <code>&lt;span&gt;</code>.</td></tr><tr><td><code>v11.1.0</code></td><td><code>onLoadingComplete</code> and <code>lazyBoundary</code> props added.</td></tr><tr><td><code>v11.0.0</code></td><td><code>src</code> prop support for static import.<br><code>placeholder</code> prop added.<br><code>blurDataURL</code> prop added.</td></tr><tr><td><code>v10.0.5</code></td><td><code>loader</code> prop added.</td></tr><tr><td><code>v10.0.1</code></td><td><code>layout</code> prop added.</td></tr><tr><td><code>v10.0.0</code></td><td><code>next/image</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components/link",
    "title": "Components: Link Component | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Link Component</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 10, 2026</div>\n<p><code>&lt;Link&gt;</code> is a React component that extends the HTML <code>&lt;a&gt;</code> element to provide <a href=\"/docs/app/getting-started/linking-and-navigating#prefetching\">prefetching</a> and client-side navigation between routes. It is the primary way to navigate between routes in Next.js.</p>\n<p>Basic usage:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Dashboard&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The following props can be passed to the <code>&lt;Link&gt;</code> component:</p>\n<!-- -->\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Prop</th><th class=\"min-w-[12ch]\">Example</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th></tr></thead><tbody><tr><td><a href=\"#href-required\"><code>href</code></a></td><td><code>href=\"/dashboard\"</code></td><td>String or Object</td><td>Yes</td></tr><tr><td><a href=\"#replace\"><code>replace</code></a></td><td><code>replace={false}</code></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#scroll\"><code>scroll</code></a></td><td><code>scroll={false}</code></td><td>Boolean</td><td>-</td></tr><tr><td><a href=\"#prefetch\"><code>prefetch</code></a></td><td><code>prefetch={false}</code></td><td>Boolean or null</td><td>-</td></tr><tr><td><a href=\"#onnavigate\"><code>onNavigate</code></a></td><td><code>onNavigate={(e) =&gt; {}}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#transitiontypes\"><code>transitionTypes</code></a></td><td><code>transitionTypes={['slide-in']}</code></td><td><code>string[]</code></td><td>-</td></tr></tbody></table></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: <code>&lt;a&gt;</code> tag attributes such as <code>className</code> or <code>target=\"_blank\"</code> can be added to <code>&lt;Link&gt;</code> as props and will be passed to the underlying <code>&lt;a&gt;</code> element.</p>\n</blockquote>\n<h3 id=\"href-required\" data-docs-heading=\"\"><code>href</code> (required)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#href-required\"><span></span></a></h3>\n<p>The path or URL to navigate to.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Navigate to /about?name=test</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        pathname</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        query</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { name</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'test'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      About</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"replace\" data-docs-heading=\"\"><code>replace</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#replace\"><span></span></a></h3>\n<p><strong>Defaults to <code>false</code>.</strong> When <code>true</code>, <code>next/link</code> will replace the current history state instead of adding a new URL into the <a href=\"https://developer.mozilla.org/docs/Web/API/History_API\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">browser's history<span class=\"inline-flex not-prose\"></span></a> stack.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span><span style=\"color:var(--shiki-token-function)\"> replace</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Dashboard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"scroll\" data-docs-heading=\"\"><code>scroll</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#scroll\"><span></span></a></h3>\n<p><strong>Defaults to <code>true</code>.</strong> The default scrolling behavior of <code>&lt;Link&gt;</code> in Next.js <strong>is to maintain scroll position</strong>, similar to how browsers handle back and forwards navigation. When you navigate to a new <a href=\"/docs/app/api-reference/file-conventions/page\">Page</a>, scroll position will stay the same as long as the Page is visible in the viewport. However, if the Page is not visible in the viewport, Next.js will scroll to the top of the first Page element.</p>\n<p>When <code>scroll = {false}</code>, Next.js will not attempt to scroll to the first Page element.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Next.js checks if <code>scroll: false</code> before managing scroll behavior. If scrolling is enabled, it identifies the relevant DOM node for navigation and inspects each top-level element. All non-scrollable elements and those without rendered HTML are bypassed, this includes sticky or fixed positioned elements, and non-visible elements such as those calculated with <code>getBoundingClientRect</code>. Next.js then continues through siblings until it identifies a scrollable element that is visible in the viewport.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span><span style=\"color:var(--shiki-token-function)\"> scroll</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Dashboard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"prefetch\" data-docs-heading=\"\"><code>prefetch</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#prefetch\"><span></span></a></h3>\n<p>Prefetching happens when a <code>&lt;Link /&gt;</code> component enters the user's viewport (initially or through scroll). Next.js prefetches and loads the linked route (denoted by the <code>href</code>) and its data in the background to improve the performance of client-side navigations. If the prefetched data has expired by the time the user hovers over a <code>&lt;Link /&gt;</code>, Next.js will attempt to prefetch it again. <strong>Prefetching is only enabled in production</strong>.</p><p>The following values can be passed to the <code>prefetch</code> prop:</p><ul>\n<li><strong><code>\"auto\"</code> or <code>null</code> (default)</strong>: Prefetch behavior depends on whether the route is static or dynamic. For static routes, the full route will be prefetched (including all its data). For dynamic routes, the partial route down to the nearest segment with a <a href=\"/docs/app/api-reference/file-conventions/loading#instant-loading-states\"><code>loading.js</code></a> boundary will be prefetched.</li>\n<li><strong><code>true</code></strong>: The full route is prefetched for both static and dynamic routes. With <a href=\"/docs/app/guides/adopting-partial-prefetching\">Partial Prefetching</a> enabled, the prefetch includes the <a href=\"/docs/app/glossary#app-shell\">App Shell</a> and cached content that depends on the link's URL data. See <a href=\"/docs/app/guides/optimizing-prefetching\">Optimizing prefetching</a>.</li>\n<li><code>false</code>: Prefetching will never happen both on entering the viewport and on hover.</li>\n</ul><blockquote class=\"p-3 text-sm\">\n<p><strong>With Partial Prefetching enabled</strong> (<a href=\"/docs/app/api-reference/config/next-config-js/partialPrefetching\"><code>partialPrefetching: true</code></a>): the default changes. <code>auto</code> prefetches the per-route <a href=\"/docs/app/glossary#app-shell\">App Shell</a> (the route's static and cached content) instead of the full page. See <a href=\"/docs/app/guides/adopting-partial-prefetching\">Adopting Partial Prefetching</a> for the full behavior change.</p>\n</blockquote><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span><span style=\"color:var(--shiki-token-function)\"> prefetch</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Dashboard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"onnavigate\" data-docs-heading=\"\"><code>onNavigate</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onnavigate\"><span></span></a></h3>\n<p>An event handler called during client-side navigation. The handler receives an event object that includes a <code>preventDefault()</code> method, allowing you to cancel the navigation if needed.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      onNavigate</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Only executes during SPA navigation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Navigating...'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Optionally prevent navigation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // e.preventDefault()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Dashboard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: While <code>onClick</code> and <code>onNavigate</code> may seem similar, they serve different purposes. <code>onClick</code> executes for all click events, while <code>onNavigate</code> only runs during client-side navigation. Some key differences:</p>\n<ul>\n<li>When using modifier keys (<code>Ctrl</code>/<code>Cmd</code> + Click), <code>onClick</code> executes but <code>onNavigate</code> doesn't since Next.js prevents default navigation for new tabs.</li>\n<li>External URLs won't trigger <code>onNavigate</code> since it's only for client-side and same-origin navigations.</li>\n<li>Links with the <code>download</code> attribute will work with <code>onClick</code> but not <code>onNavigate</code> since the browser will treat the linked URL as a download.</li>\n</ul>\n</blockquote>\n<h3 id=\"transitiontypes\" data-docs-heading=\"\"><code>transitionTypes</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#transitiontypes\"><span></span></a></h3>\n<p>A list of transition types to apply to the navigation. These types are passed to <a href=\"https://react.dev/reference/react/addTransitionType\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>React.addTransitionType</code><span class=\"inline-flex not-prose\"></span></a> inside the navigation transition, enabling <a href=\"https://react.dev/reference/react/ViewTransition\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>&lt;ViewTransition&gt;</code><span class=\"inline-flex not-prose\"></span></a> components to apply different animations based on the type of navigation.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span><span style=\"color:var(--shiki-token-function)\"> transitionTypes</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{[</span><span style=\"color:var(--shiki-token-string-expression)\">'slide-in'</span><span style=\"color:var(--shiki-color-text)\">]}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      About</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<p>The following examples demonstrate how to use the <code>&lt;Link&gt;</code> component in different scenarios.</p>\n<h3 id=\"linking-to-dynamic-route-segments\" data-docs-heading=\"\">Linking to dynamic route segments<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#linking-to-dynamic-route-segments\"><span></span></a></h3><p>When linking to <a href=\"/docs/app/api-reference/file-conventions/dynamic-routes\">dynamic segments</a>, you can use <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">template literals and interpolation<span class=\"inline-flex not-prose\"></span></a> to generate a list of links. For example, to generate a list of blog posts:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/blog/post-list.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">interface</span><span style=\"color:var(--shiki-token-function)\"> Post</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  slug</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> PostList</span><span style=\"color:var(--shiki-color-text)\">({ posts }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { posts</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Post</span><span style=\"color:var(--shiki-color-text)\">[] }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">ul</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-constant)\">posts</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((post) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">li</span><span style=\"color:var(--shiki-token-function)\"> key</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">post</span><span style=\"color:var(--shiki-color-text)\">.id}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`/blog/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">post</span><span style=\"color:var(--shiki-color-text)\">.slug</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">}&gt;{</span><span style=\"color:var(--shiki-token-constant)\">post</span><span style=\"color:var(--shiki-color-text)\">.title}&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">li</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ))}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">ul</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><h3 id=\"checking-active-links\" data-docs-heading=\"\">Checking active links<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#checking-active-links\"><span></span></a></h3><p>You can use <a href=\"/docs/app/api-reference/functions/use-pathname\"><code>usePathname()</code></a> to determine if a link is active. For example, to add a class to the active link, you can check if the current <code>pathname</code> matches the <code>href</code> of the link:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/ui/nav-links.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { usePathname } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/navigation'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Links</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> pathname</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> usePathname</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`link </span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">pathname </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-keyword)\"> ?</span><span style=\"color:var(--shiki-token-string-expression)\"> 'active'</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-function)\">href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        Home</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`link </span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">pathname </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-keyword)\"> ?</span><span style=\"color:var(--shiki-token-string-expression)\"> 'active'</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> ''</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        About</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"scrolling-to-an-id\" data-docs-heading=\"\">Scrolling to an <code>id</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#scrolling-to-an-id\"><span></span></a></h3>\n<p>If you'd like to scroll to a specific <code>id</code> on navigation, you can append your URL with a <code>#</code> hash link or just pass a hash link to the <code>href</code> prop. This is possible since <code>&lt;Link&gt;</code> renders to an <code>&lt;a&gt;</code> element.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard#settings\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Settings&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Output</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">a</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard#settings\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Settings&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">a</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>Next.js will scroll to the <a href=\"/docs/app/api-reference/file-conventions/page\">Page</a> if it is not visible in the viewport upon navigation.</li>\n</ul>\n</blockquote>\n<!-- -->\n<h3 id=\"replace-the-url-instead-of-push\" data-docs-heading=\"\">Replace the URL instead of push<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#replace-the-url-instead-of-push\"><span></span></a></h3>\n<p>The default behavior of the <code>Link</code> component is to <code>push</code> a new URL into the <code>history</code> stack. You can use the <code>replace</code> prop to prevent adding a new entry, as in the following example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span><span style=\"color:var(--shiki-token-function)\"> replace</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      About us</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"disable-scrolling-to-the-top-of-the-page\" data-docs-heading=\"\">Disable scrolling to the top of the page<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disable-scrolling-to-the-top-of-the-page\"><span></span></a></h3>\n<p>The default scrolling behavior of <code>&lt;Link&gt;</code> in Next.js <strong>is to maintain scroll position</strong>, similar to how browsers handle back and forwards navigation. When you navigate to a new <a href=\"/docs/app/api-reference/file-conventions/page\">Page</a>, scroll position will stay the same as long as the Page is visible in the viewport.</p><p>However, if the Page is not visible in the viewport, Next.js will scroll to the top of the first Page element. If you'd like to disable this behavior, you can pass <code>scroll={false}</code> to the <code>&lt;Link&gt;</code> component, or <code>scroll: false</code> to <code>router.push()</code> or <code>router.replace()</code>.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/#hashid\"</span><span style=\"color:var(--shiki-token-function)\"> scroll</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Disables scrolling to the top</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Using <code>router.push()</code> or <code>router.replace()</code>:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// useRouter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useRouter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/navigation'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> useRouter</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">router</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/dashboard'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { scroll</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-color-text)\"> })</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"scroll-offset-with-sticky-headers\" data-docs-heading=\"\">Scroll offset with sticky headers<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#scroll-offset-with-sticky-headers\"><span></span></a></h3>\n<p>Because Next.js skips sticky and fixed positioned elements when finding the scroll target, content may end up behind a sticky header after navigation. For example, if your layout has a sticky header:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-string-expression)\"> './globals.css'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">header</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"sticky top-0 h-16 bg-white\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span><span style=\"color:var(--shiki-token-comment)\">/* Navigation */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">header</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>You can account for its height using <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>scroll-padding-top</code><span class=\"inline-flex not-prose\"></span></a> on the scroll container:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/globals.css</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  scroll-padding-top</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 64</span><span style=\"color:var(--shiki-token-keyword)\">px</span><span style=\"color:var(--shiki-color-text)\">; </span><span style=\"color:var(--shiki-token-comment)\">/* Match the height of your sticky header */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This is a browser CSS property that offsets scroll-based positioning. It applies whenever Next.js uses the native <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>scrollIntoView()</code><span class=\"inline-flex not-prose\"></span></a> API, including hash fragment (<code>#id</code>) navigation. Alternatively, you can use <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>scroll-margin-top</code><span class=\"inline-flex not-prose\"></span></a> on individual target elements instead of setting a global offset.</p>\n<h3 id=\"prefetching-links-in-proxy\" data-docs-heading=\"\">Prefetching links in Proxy<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#prefetching-links-in-proxy\"><span></span></a></h3>\n<p>It's common to use <a href=\"/docs/app/api-reference/file-conventions/proxy\">Proxy</a> for authentication or other purposes that involve rewriting the user to a different page. In order for the <code>&lt;Link /&gt;</code> component to properly prefetch links with rewrites via Proxy, you need to tell Next.js both the URL to display and the URL to prefetch. This is required to avoid un-necessary fetches to proxy to know the correct route to prefetch.</p>\n<p>For example, if you want to serve a <code>/dashboard</code> route that has authenticated and visitor views, you can add the following in your Proxy to redirect the user to the correct page:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">proxy.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { NextResponse } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> proxy</span><span style=\"color:var(--shiki-color-text)\">(request</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Request</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> nextUrl</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-color-text)\">.nextUrl</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">nextUrl</span><span style=\"color:var(--shiki-color-text)\">.pathname </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> '/dashboard'</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">request</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">cookies</span><span style=\"color:var(--shiki-color-text)\">.authToken) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.rewrite</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/auth/dashboard'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-color-text)\">.url))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    } </span><span style=\"color:var(--shiki-token-keyword)\">else</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.rewrite</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/public/dashboard'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-color-text)\">.url))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>In this case, you would want to use the following code in your <code>&lt;Link /&gt;</code> component:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> useIsAuthed </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './hooks/useIsAuthed'</span><span style=\"color:var(--shiki-token-comment)\"> // Your auth hook</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> isAuthed</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> useIsAuthed</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> isAuthed </span><span style=\"color:var(--shiki-token-keyword)\">?</span><span style=\"color:var(--shiki-token-string-expression)\"> '/auth/dashboard'</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> '/public/dashboard'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> as</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/dashboard\"</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{path}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Dashboard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"blocking-navigation\" data-docs-heading=\"\">Blocking navigation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#blocking-navigation\"><span></span></a></h3><p>You can use the <code>onNavigate</code> prop to block navigation when certain conditions are met, such as when a form has unsaved changes. When you need to block navigation across multiple components in your app (like preventing navigation from any link while a form is being edited), React Context provides a clean way to share this blocking state. First, create a context to track the navigation blocking state:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/contexts/navigation-blocker.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { createContext</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> useState</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> useContext } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">interface</span><span style=\"color:var(--shiki-token-function)\"> NavigationBlockerContextType</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  isBlocked</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> boolean</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  setIsBlocked</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> (isBlocked</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> boolean</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> void</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> const</span><span style=\"color:var(--shiki-token-constant)\"> NavigationBlockerContext</span><span style=\"color:var(--shiki-token-keyword)\"> =</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  createContext</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">NavigationBlockerContextType</span><span style=\"color:var(--shiki-color-text)\">&gt;({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    isBlocked</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    setIsBlocked</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {}</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  })</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> NavigationBlockerProvider</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">isBlocked</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> setIsBlocked</span><span style=\"color:var(--shiki-color-text)\">] </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> useState</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">NavigationBlockerContext.Provider</span><span style=\"color:var(--shiki-token-function)\"> value</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{{ isBlocked</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> setIsBlocked }}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">NavigationBlockerContext.Provider</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> useNavigationBlocker</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> useContext</span><span style=\"color:var(--shiki-color-text)\">(NavigationBlockerContext)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Create a form component that uses the context:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/form.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useNavigationBlocker } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../contexts/navigation-blocker'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Form</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">setIsBlocked</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> useNavigationBlocker</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">form</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      onSubmit</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        e</span><span style=\"color:var(--shiki-token-function)\">.preventDefault</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        setIsBlocked</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">false</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      onChange</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> setIsBlocked</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">true</span><span style=\"color:var(--shiki-color-text)\">)}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">input</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"text\"</span><span style=\"color:var(--shiki-token-function)\"> name</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"name\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"submit\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Save&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Create a custom Link component that blocks navigation:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/custom-link.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useNavigationBlocker } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../contexts/navigation-blocker'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">interface</span><span style=\"color:var(--shiki-token-function)\"> CustomLinkProps</span><span style=\"color:var(--shiki-token-keyword)\"> extends</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ComponentProps</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-keyword)\">typeof</span><span style=\"color:var(--shiki-color-text)\"> Link&gt; {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> CustomLink</span><span style=\"color:var(--shiki-color-text)\">({ children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-keyword)\"> ...</span><span style=\"color:var(--shiki-color-text)\">props }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> CustomLinkProps</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">isBlocked</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> useNavigationBlocker</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      onNavigate</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        if</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          isBlocked </span><span style=\"color:var(--shiki-token-keyword)\">&amp;&amp;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          !</span><span style=\"color:var(--shiki-token-constant)\">window</span><span style=\"color:var(--shiki-token-function)\">.confirm</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'You have unsaved changes. Leave anyway?'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          e</span><span style=\"color:var(--shiki-token-function)\">.preventDefault</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">props}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Create a navigation component:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/nav.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { CustomLink </span><span style=\"color:var(--shiki-token-keyword)\">as</span><span style=\"color:var(--shiki-color-text)\"> Link } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './custom-link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Nav</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/\"</span><span style=\"color:var(--shiki-color-text)\">&gt;Home&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span><span style=\"color:var(--shiki-color-text)\">&gt;About&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Finally, wrap your app with the <code>NavigationBlockerProvider</code> in the root layout and use the components in your page:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { NavigationBlockerProvider } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './contexts/navigation-blocker'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">NavigationBlockerProvider</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-constant)\">NavigationBlockerProvider</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Then, use the <code>Nav</code> and <code>Form</code> components in your page:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Nav </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './components/nav'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Form </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './components/form'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Nav</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;Welcome to the Dashboard&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Form</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>When a user tries to navigate away using <code>CustomLink</code> while the form has unsaved changes, they'll be prompted to confirm before leaving.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version history<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.2.0</code></td><td>Add <code>transitionTypes</code> prop.</td></tr><tr><td><code>v15.4.0</code></td><td>Add <code>auto</code> as an alias to the default <code>prefetch</code> behavior.</td></tr><tr><td><code>v15.3.0</code></td><td>Add <code>onNavigate</code> API</td></tr><tr><td><code>v13.0.0</code></td><td>No longer requires a child <code>&lt;a&gt;</code> tag. A <a href=\"/docs/app/guides/upgrading/codemods#remove-a-tags-from-link-components\">codemod</a> is provided to automatically update your codebase.</td></tr><tr><td><code>v10.0.0</code></td><td><code>href</code> props pointing to a dynamic route are automatically resolved and no longer require an <code>as</code> prop.</td></tr><tr><td><code>v8.0.0</code></td><td>Improved prefetching performance.</td></tr><tr><td><code>v1.0.0</code></td><td><code>next/link</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/components/script",
    "title": "Components: Script Component | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Script Component</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>This API reference will help you understand how to use <a href=\"#props\">props</a> available for the Script Component. For features and usage, please see the <a href=\"/docs/app/guides/scripts\">Optimizing Scripts</a> page.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/dashboard/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dashboard</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"props\" data-docs-heading=\"\">Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#props\"><span></span></a></h2>\n<p>Here's a summary of the props available for the Script Component:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Prop</th><th class=\"min-w-[12ch]\">Example</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th></tr></thead><tbody><tr><td><a href=\"#src\"><code>src</code></a></td><td><code>src=\"http://example.com/script\"</code></td><td>String</td><td>Required unless inline script is used</td></tr><tr><td><a href=\"#strategy\"><code>strategy</code></a></td><td><code>strategy=\"lazyOnload\"</code></td><td>String</td><td>-</td></tr><tr><td><a href=\"#onload\"><code>onLoad</code></a></td><td><code>onLoad={onLoadFunc}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#onready\"><code>onReady</code></a></td><td><code>onReady={onReadyFunc}</code></td><td>Function</td><td>-</td></tr><tr><td><a href=\"#onerror\"><code>onError</code></a></td><td><code>onError={onErrorFunc}</code></td><td>Function</td><td>-</td></tr></tbody></table></div>\n<h2 id=\"required-props\" data-docs-heading=\"\">Required Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#required-props\"><span></span></a></h2>\n<p>The <code>&lt;Script /&gt;</code> component requires the following properties.</p>\n<h3 id=\"src\" data-docs-heading=\"\"><code>src</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#src\"><span></span></a></h3>\n<p>A path string specifying the URL of an external script. This can be either an absolute external URL or an internal path. The <code>src</code> property is required unless an inline script is used.</p>\n<h2 id=\"optional-props\" data-docs-heading=\"\">Optional Props<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#optional-props\"><span></span></a></h2>\n<p>The <code>&lt;Script /&gt;</code> component accepts a number of additional properties beyond those which are required.</p>\n<h3 id=\"strategy\" data-docs-heading=\"\"><code>strategy</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#strategy\"><span></span></a></h3>\n<p>The loading strategy of the script. There are four different strategies that can be used:</p>\n<ul>\n<li><code>beforeInteractive</code>: Load before any Next.js code and before any page hydration occurs.</li>\n<li><code>afterInteractive</code>: (<strong>default</strong>) Load early but after some hydration on the page occurs.</li>\n<li><code>lazyOnload</code>: Load during browser idle time.</li>\n<li><code>worker</code>: (experimental) Load in a web worker.</li>\n</ul>\n<h3 id=\"beforeinteractive\" data-docs-heading=\"\"><code>beforeInteractive</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#beforeinteractive\"><span></span></a></h3>\n<p>Scripts that load with the <code>beforeInteractive</code> strategy are injected into the initial HTML from the server, downloaded before any Next.js module, and executed in the order they are placed.</p>\n<p>Scripts denoted with this strategy are preloaded and fetched before any first-party code, but their execution <strong>does not block page hydration from occurring</strong>.</p>\n<p><code>beforeInteractive</code> scripts must be placed inside the root layout (<code>app/layout.tsx</code>) and are designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).</p>\n<!-- -->\n<p><strong>This strategy should only be used for critical scripts that need to be fetched as soon as possible.</strong></p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> RootLayout</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> React</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-function)\">ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-token-function)\"> lang</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"en\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">          strategy</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"beforeInteractive\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">body</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">html</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Scripts with <code>beforeInteractive</code> will always be injected inside the <code>head</code> of the HTML document regardless of where it's placed in the component.</p>\n</blockquote>\n<p>Some examples of scripts that should be fetched as soon as possible with <code>beforeInteractive</code> include:</p>\n<ul>\n<li>Bot detectors</li>\n<li>Cookie consent managers</li>\n</ul>\n<h3 id=\"afterinteractive\" data-docs-heading=\"\"><code>afterInteractive</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#afterinteractive\"><span></span></a></h3>\n<p>Scripts that use the <code>afterInteractive</code> strategy are injected into the HTML client-side and will load after some (or all) hydration occurs on the page. <strong>This is the default strategy</strong> of the Script component and should be used for any script that needs to load as soon as possible but not before any first-party Next.js code.</p>\n<p><code>afterInteractive</code> scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span><span style=\"color:var(--shiki-token-function)\"> strategy</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"afterInteractive\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Some examples of scripts that are good candidates for <code>afterInteractive</code> include:</p>\n<ul>\n<li>Tag managers</li>\n<li>Analytics</li>\n</ul>\n<h3 id=\"lazyonload\" data-docs-heading=\"\"><code>lazyOnload</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#lazyonload\"><span></span></a></h3>\n<p>Scripts that use the <code>lazyOnload</code> strategy are injected into the HTML client-side during browser idle time and will load after all resources on the page have been fetched. This strategy should be used for any background or low priority scripts that do not need to load early.</p>\n<p><code>lazyOnload</code> scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span><span style=\"color:var(--shiki-token-function)\"> strategy</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"lazyOnload\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Examples of scripts that do not need to load immediately and can be fetched with <code>lazyOnload</code> include:</p>\n<ul>\n<li>Chat support plugins</li>\n<li>Social media widgets</li>\n</ul>\n<h3 id=\"worker\" data-docs-heading=\"\"><code>worker</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#worker\"><span></span></a></h3>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning:</strong> The <code>worker</code> strategy is not yet stable and does not yet work with the App Router. Use with caution.</p>\n</blockquote>\n<p>Scripts that use the <code>worker</code> strategy are off-loaded to a web worker in order to free up the main thread and ensure that only critical, first-party resources are processed on it. While this strategy can be used for any script, it is an advanced use case that is not guaranteed to support all third-party scripts.</p>\n<p>To use <code>worker</code> as a strategy, the <code>nextScriptWorkers</code> flag must be enabled in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    nextScriptWorkers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>worker</code> scripts can <strong>only currently be used in the <code>pages/</code> directory</strong>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">pages/home.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Home</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span><span style=\"color:var(--shiki-token-function)\"> strategy</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"worker\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"onload\" data-docs-heading=\"\"><code>onLoad</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onload\"><span></span></a></h3>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning:</strong> <code>onLoad</code> does not yet work with Server Components and can only be used in Client Components. Further, <code>onLoad</code> can't be used with <code>beforeInteractive</code> – consider using <code>onReady</code> instead.</p>\n</blockquote>\n<p>Some third-party scripts require users to run JavaScript code once after the script has finished loading in order to instantiate content or call a function. If you are loading a script with either <code>afterInteractive</code> or <code>lazyOnload</code> as a loading strategy, you can execute code after it has loaded using the <code>onLoad</code> property.</p>\n<p>Here's an example of executing a lodash method only after the library has been loaded.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        onLoad</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">_</span><span style=\"color:var(--shiki-token-function)\">.sample</span><span style=\"color:var(--shiki-color-text)\">([</span><span style=\"color:var(--shiki-token-constant)\">1</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 2</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 3</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 4</span><span style=\"color:var(--shiki-color-text)\">]))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"onready\" data-docs-heading=\"\"><code>onReady</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onready\"><span></span></a></h3>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning:</strong> <code>onReady</code> does not yet work with Server Components and can only be used in Client Components.</p>\n</blockquote>\n<p>Some third-party scripts require users to run JavaScript code after the script has finished loading and every time the component is mounted (after a route navigation for example). You can execute code after the script's load event when it first loads and then after every subsequent component re-mount using the <code>onReady</code> property.</p>\n<p>Here's an example of how to re-instantiate a Google Maps JS embed every time the component is mounted:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useRef } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> mapRef</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> useRef</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> ref</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{mapRef}&gt;&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        id</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"google-maps\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://maps.googleapis.com/maps/api/js\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        onReady</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">          new</span><span style=\"color:var(--shiki-token-constant)\"> google</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">maps</span><span style=\"color:var(--shiki-token-function)\">.Map</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">mapRef</span><span style=\"color:var(--shiki-color-text)\">.current</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            center</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { lat</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> -</span><span style=\"color:var(--shiki-token-constant)\">34.397</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> lng</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 150.644</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            zoom</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 8</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"onerror\" data-docs-heading=\"\"><code>onError</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#onerror\"><span></span></a></h3>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning:</strong> <code>onError</code> does not yet work with Server Components and can only be used in Client Components. <code>onError</code> cannot be used with the <code>beforeInteractive</code> loading strategy.</p>\n</blockquote>\n<p>Sometimes it is helpful to catch when a script fails to load. These errors can be handled with the <code>onError</code> property:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Script </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/script'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Script</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"https://example.com/script.js\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        onError</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(e</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Error</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          console</span><span style=\"color:var(--shiki-token-function)\">.error</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Script failed to load'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> e)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.0.0</code></td><td><code>beforeInteractive</code> and <code>afterInteractive</code> is modified to support <code>app</code>.</td></tr><tr><td><code>v12.2.4</code></td><td><code>onReady</code> prop added.</td></tr><tr><td><code>v12.2.2</code></td><td>Allow <code>next/script</code> with <code>beforeInteractive</code> to be placed in <code>_document</code>.</td></tr><tr><td><code>v11.0.0</code></td><td><code>next/script</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config",
    "title": "API Reference: Configuration | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Configuration</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">next.config.js</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to configure your application with next.config.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/typescript\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">TypeScript</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js provides a TypeScript-first development experience for building your React application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/eslint\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">ESLint</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use and configure the ESLint plugin to catch common issues and problems in a Next.js application.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/eslint",
    "title": "Configuration: ESLint | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">ESLint Plugin</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->November 10, 2025</div>\n<p>Next.js provides an ESLint configuration package, <a href=\"https://www.npmjs.com/package/eslint-config-next\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>eslint-config-next</code><span class=\"inline-flex not-prose\"></span></a>, that makes it easy to catch common issues in your application. It includes the <a href=\"https://www.npmjs.com/package/@next/eslint-plugin-next\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>@next/eslint-plugin-next</code><span class=\"inline-flex not-prose\"></span></a> plugin along with recommended rule-sets from <a href=\"https://www.npmjs.com/package/eslint-plugin-react\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>eslint-plugin-react</code><span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>eslint-plugin-react-hooks</code><span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>The package provides two main configurations:</p>\n<ul>\n<li><strong><code>eslint-config-next</code></strong>: Base configuration with Next.js, React, and React Hooks rules. Supports both JavaScript and TypeScript files.</li>\n<li><strong><code>eslint-config-next/core-web-vitals</code></strong>: Includes everything from the base config, plus upgrades rules that impact <a href=\"https://web.dev/vitals/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Core Web Vitals<span class=\"inline-flex not-prose\"></span></a> from warnings to errors. Recommended for most projects.</li>\n</ul>\n<p>Additionally, for TypeScript projects:</p>\n<ul>\n<li><strong><code>eslint-config-next/typescript</code></strong>: Adds TypeScript-specific linting rules from <a href=\"https://typescript-eslint.io/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>typescript-eslint</code><span class=\"inline-flex not-prose\"></span></a>. Use this alongside the base or core-web-vitals config.</li>\n</ul>\n<h2 id=\"setup-eslint\" data-docs-heading=\"\">Setup ESLint<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#setup-eslint\"><span></span></a></h2>\n<p>Get linting working quickly with the ESLint CLI (flat config):</p>\n<ol>\n<li>\n<p>Install ESLint and the Next.js config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_55222otbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_55222otbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_95222otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_95222otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_d5222otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_d5222otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_h5222otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_h5222otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> eslint</span><span style=\"color:var(--shiki-token-string)\"> eslint-config-next</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n</li>\n<li>\n<p>Create <code>eslint.config.mjs</code> with the Next.js config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> globalIgnores } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextVitals </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextVitals</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Override default ignores of eslint-config-next.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  globalIgnores</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default ignores of eslint-config-next:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '.next/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'out/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'build/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'next-env.d.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n</li>\n<li>\n<p>Run ESLint:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_55622otbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_55622otbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_95622otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_95622otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_d5622otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_d5622otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_h5622otbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_h5622otbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> exec</span><span style=\"color:var(--shiki-token-string)\"> eslint</span><span style=\"color:var(--shiki-token-string)\"> .</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n</li>\n</ol>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The <code>eslint-config-next</code> package includes the <code>recommended</code> rule-sets from the following ESLint plugins:</p>\n<ul>\n<li><a href=\"https://www.npmjs.com/package/eslint-plugin-react\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>eslint-plugin-react</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>eslint-plugin-react-hooks</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/@next/eslint-plugin-next\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>@next/eslint-plugin-next</code><span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h3 id=\"rules\" data-docs-heading=\"\">Rules<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#rules\"><span></span></a></h3>\n<p>The <code>@next/eslint-plugin-next</code> rules included are:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\" style=\"text-align:center\">Enabled in recommended config</th><th class=\"min-w-[12ch]\">Rule</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/google-font-display\">@next/next/google-font-display</a></td><td>Enforce font-display behavior with Google Fonts.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/google-font-preconnect\">@next/next/google-font-preconnect</a></td><td>Ensure <code>preconnect</code> is used with Google Fonts.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/inline-script-id\">@next/next/inline-script-id</a></td><td>Enforce <code>id</code> attribute on <code>next/script</code> components with inline content.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/next-script-for-ga\">@next/next/next-script-for-ga</a></td><td>Prefer <code>next/script</code> component when using the inline script for Google Analytics.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-assign-module-variable\">@next/next/no-assign-module-variable</a></td><td>Prevent assignment to the <code>module</code> variable.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-async-client-component\">@next/next/no-async-client-component</a></td><td>Prevent Client Components from being async functions.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-before-interactive-script-outside-document\">@next/next/no-before-interactive-script-outside-document</a></td><td>Prevent usage of <code>next/script</code>'s <code>beforeInteractive</code> strategy outside of <code>pages/_document.js</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-css-tags\">@next/next/no-css-tags</a></td><td>Prevent manual stylesheet tags.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-document-import-in-page\">@next/next/no-document-import-in-page</a></td><td>Prevent importing <code>next/document</code> outside of <code>pages/_document.js</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-duplicate-head\">@next/next/no-duplicate-head</a></td><td>Prevent duplicate usage of <code>&lt;Head&gt;</code> in <code>pages/_document.js</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-head-element\">@next/next/no-head-element</a></td><td>Prevent usage of <code>&lt;head&gt;</code> element.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-head-import-in-document\">@next/next/no-head-import-in-document</a></td><td>Prevent usage of <code>next/head</code> in <code>pages/_document.js</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-html-link-for-pages\">@next/next/no-html-link-for-pages</a></td><td>Prevent usage of <code>&lt;a&gt;</code> elements to navigate to internal Next.js pages.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-img-element\">@next/next/no-img-element</a></td><td>Prevent usage of <code>&lt;img&gt;</code> element due to slower LCP and higher bandwidth.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-page-custom-font\">@next/next/no-page-custom-font</a></td><td>Prevent page-only custom fonts.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-script-component-in-head\">@next/next/no-script-component-in-head</a></td><td>Prevent usage of <code>next/script</code> in <code>next/head</code> component.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-styled-jsx-in-document\">@next/next/no-styled-jsx-in-document</a></td><td>Prevent usage of <code>styled-jsx</code> in <code>pages/_document.js</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-sync-scripts\">@next/next/no-sync-scripts</a></td><td>Prevent synchronous scripts.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-title-in-document-head\">@next/next/no-title-in-document-head</a></td><td>Prevent usage of <code>&lt;title&gt;</code> with <code>Head</code> component from <code>next/document</code>.</td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td>@next/next/no-typos</td><td>Prevent common typos in <a href=\"/docs/pages/building-your-application/data-fetching\">Next.js's data fetching functions</a></td></tr><tr><td style=\"text-align:center\"><span class=\"inline-flex align-middle text-green-600\"></span></td><td><a href=\"/docs/messages/no-unwanted-polyfillio\">@next/next/no-unwanted-polyfillio</a></td><td>Prevent duplicate polyfills from Polyfill.io.</td></tr></tbody></table></div>\n<p>We recommend using an appropriate <a href=\"https://eslint.org/docs/user-guide/integrations#editors\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">integration<span class=\"inline-flex not-prose\"></span></a> to view warnings and errors directly in your code editor during development.</p>\n<details><summary><code>next lint</code> removal</summary><p>Starting with Next.js 16, <code>next lint</code> is removed.</p><p>As part of the removal, the <code>eslint</code> option in your Next config file is no longer needed and can be safely removed.</p></details>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"specifying-a-root-directory-within-a-monorepo\" data-docs-heading=\"\">Specifying a root directory within a monorepo<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#specifying-a-root-directory-within-a-monorepo\"><span></span></a></h3>\n<p>If you're using <code>@next/eslint-plugin-next</code> in a project where Next.js isn't installed in your root directory (such as a monorepo), you can tell <code>@next/eslint-plugin-next</code> where to find your Next.js application using the <code>settings</code> property in your <code>eslint.config.mjs</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> eslintNextPlugin </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@next/eslint-plugin-next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    files</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'**/*.{js,jsx,ts,tsx}'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    plugins</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      next</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> eslintNextPlugin</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    settings</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      next</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        rootDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'packages/my-app/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<p><code>rootDir</code> can be a path (relative or absolute), a glob (i.e. <code>\"packages/*/\"</code>), or an array of paths and/or globs.</p>\n<h3 id=\"disabling-rules\" data-docs-heading=\"\">Disabling rules<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disabling-rules\"><span></span></a></h3>\n<p>If you would like to modify or disable any rules provided by the supported plugins (<code>react</code>, <code>react-hooks</code>, <code>next</code>), you can directly change them using the <code>rules</code> property in your <code>eslint.config.mjs</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> globalIgnores } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextVitals </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextVitals</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      'react/no-unescaped-entities'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'off'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '@next/next/no-page-custom-font'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'off'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Override default ignores of eslint-config-next.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  globalIgnores</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default ignores of eslint-config-next:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '.next/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'out/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'build/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'next-env.d.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<h3 id=\"with-core-web-vitals\" data-docs-heading=\"\">With Core Web Vitals<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-core-web-vitals\"><span></span></a></h3>\n<p>Enable the <code>eslint-config-next/core-web-vitals</code> configuration in your ESLint config.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> globalIgnores } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextVitals </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextVitals</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Override default ignores of eslint-config-next.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  globalIgnores</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default ignores of eslint-config-next:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '.next/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'out/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'build/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'next-env.d.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<p><code>eslint-config-next/core-web-vitals</code> upgrades certain lint rules in <code>@next/eslint-plugin-next</code> from warnings to errors to help improve your <a href=\"https://web.dev/vitals/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Core Web Vitals<span class=\"inline-flex not-prose\"></span></a> metrics.</p>\n<blockquote class=\"p-3 text-sm\">\n<p>The <code>eslint-config-next/core-web-vitals</code> configuration is automatically included for new applications built with <a href=\"/docs/app/api-reference/cli/create-next-app\">Create Next App</a>.</p>\n</blockquote>\n<h3 id=\"with-typescript\" data-docs-heading=\"\">With TypeScript<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-typescript\"><span></span></a></h3>\n<p>In addition to the Next.js ESLint rules, <code>create-next-app --typescript</code> will also add TypeScript-specific lint rules with <code>eslint-config-next/typescript</code> to your config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> globalIgnores } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextVitals </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextTs </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/typescript'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextVitals</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextTs</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Override default ignores of eslint-config-next.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  globalIgnores</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default ignores of eslint-config-next:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '.next/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'out/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'build/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'next-env.d.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<p>Those rules are based on <a href=\"https://typescript-eslint.io/linting/configs#recommended\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>plugin:@typescript-eslint/recommended</code><span class=\"inline-flex not-prose\"></span></a>.\nSee <a href=\"https://typescript-eslint.io/linting/configs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">typescript-eslint &gt; Configs<span class=\"inline-flex not-prose\"></span></a> for more details.</p>\n<h3 id=\"with-prettier\" data-docs-heading=\"\">With Prettier<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-prettier\"><span></span></a></h3>\n<p>ESLint also contains code formatting rules, which can conflict with your existing <a href=\"https://prettier.io/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Prettier<span class=\"inline-flex not-prose\"></span></a> setup. We recommend including <a href=\"https://github.com/prettier/eslint-config-prettier\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">eslint-config-prettier<span class=\"inline-flex not-prose\"></span></a> in your ESLint config to make ESLint and Prettier work together.</p>\n<p>First, install the dependency:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_199aotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_199aotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_299aotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_299aotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_399aotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_399aotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_499aotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_499aotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> eslint-config-prettier</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>Then, add <code>prettier</code> to your existing ESLint config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> globalIgnores } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextVitals </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> prettier </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-prettier/flat'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextVitals</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  prettier</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Override default ignores of eslint-config-next.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  globalIgnores</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Default ignores of eslint-config-next:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '.next/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'out/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'build/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'next-env.d.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<h3 id=\"running-lint-on-staged-files\" data-docs-heading=\"\">Running lint on staged files<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#running-lint-on-staged-files\"><span></span></a></h3>\n<p>If you would like to use ESLint with <a href=\"https://github.com/okonet/lint-staged\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">lint-staged<span class=\"inline-flex not-prose\"></span></a> to run the linter on staged git files, add the following to the <code>.lintstagedrc.js</code> file in the root of your project:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">.lintstagedrc.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'path'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-function)\"> buildEslintCommand</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> (filenames) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  `eslint --fix </span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">filenames</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    .map</span><span style=\"color:var(--shiki-color-text)\">((f) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-string-expression)\"> `\"</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">path</span><span style=\"color:var(--shiki-token-function)\">.relative</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">process</span><span style=\"color:var(--shiki-token-function)\">.cwd</span><span style=\"color:var(--shiki-color-text)\">()</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> f)</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">\"`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    .join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">' '</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  '*.{js,jsx,ts,tsx}'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [buildEslintCommand]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"migrating-existing-config\" data-docs-heading=\"\">Migrating existing config<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#migrating-existing-config\"><span></span></a></h2>\n<p>If you already have ESLint configured in your application, there are two approaches to integrate Next.js linting rules, depending on your setup.</p>\n<h4 id=\"using-the-plugin-directly\" data-docs-heading=\"\">Using the plugin directly<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-the-plugin-directly\"><span></span></a></h4>\n<p>Use <code>@next/eslint-plugin-next</code> directly if you have any of the following already configured:</p>\n<ul>\n<li>Conflicting plugins installed separately or through another config (such as <code>airbnb</code> or <code>react-app</code>):<!-- -->\n<ul>\n<li><code>react</code></li>\n<li><code>react-hooks</code></li>\n<li><code>jsx-a11y</code></li>\n<li><code>import</code></li>\n</ul>\n</li>\n<li>Custom <code>parserOptions</code> different from Next.js defaults (only if you have <a href=\"/docs/pages/guides/babel\">customized your Babel configuration</a>)</li>\n<li><code>eslint-plugin-import</code> with custom Node.js and/or TypeScript <a href=\"https://github.com/benmosher/eslint-plugin-import#resolvers\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">resolvers<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<p>In these cases, use <code>@next/eslint-plugin-next</code> directly to avoid conflicts:</p>\n<p>First, install the plugin:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_19daotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_19daotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_29daotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_29daotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_39daotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_39daotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_49daotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_49daotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> @next/eslint-plugin-next</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>Then add it to your ESLint config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { defineConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint/config'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextPlugin </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '@next/eslint-plugin-next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> defineConfig</span><span style=\"color:var(--shiki-color-text)\">([</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Your other configurations...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    files</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'**/*.{js,jsx,ts,tsx}'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    plugins</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '@next/next'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> nextPlugin</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      ...</span><span style=\"color:var(--shiki-token-constant)\">nextPlugin</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">configs</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">recommended</span><span style=\"color:var(--shiki-color-text)\">.rules</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">])</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<p>This approach eliminates the risk of collisions or errors that can occur when the same plugins or parsers are imported across multiple configurations.</p>\n<h4 id=\"adding-to-existing-config\" data-docs-heading=\"\">Adding to existing config<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#adding-to-existing-config\"><span></span></a></h4>\n<p>If you're adding Next.js to an existing ESLint setup, spread the Next.js config into your array:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">eslint.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> nextConfig </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'eslint-config-next/core-web-vitals'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Your other config imports...</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> eslintConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Your other configurations...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  ...</span><span style=\"color:var(--shiki-color-text)\">nextConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> eslintConfig</span></span></code></pre></div>\n<p>When you spread <code>...nextConfig</code>, you're adding multiple config objects that include file patterns, plugins, rules, ignores, and parser settings. ESLint applies configs in order, so later rules can override earlier ones for matching files.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> This approach works well for straightforward setups. If you have a complex existing config with specific file patterns or plugin configurations that conflict, consider using the plugin directly (as shown above) for more granular control.</p>\n</blockquote>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.0.0</code></td><td><code>next lint</code> and the <code>eslint</code> next.config.js option were removed in favor of the ESLint CLI. A <a href=\"/docs/app/guides/upgrading/codemods#migrate-from-next-lint-to-eslint-cli\">codemod</a> is available to help you migrate.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js",
    "title": "Configuration: next.config.js | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">next.config.js</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->November 4, 2025</div>\n<p>Next.js can be configured through a <code>next.config.js</code> file in the root of your project directory (for example, by <code>package.json</code>) with a default export.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<h2 id=\"ecmascript-modules\" data-docs-heading=\"\">ECMAScript Modules<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#ecmascript-modules\"><span></span></a></h2>\n<p><code>next.config.js</code> is a regular Node.js module, not a JSON file. It gets used by the Next.js server and build phases, and it's not included in the browser build.</p>\n<p>If you need <a href=\"https://nodejs.org/api/esm.html\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">ECMAScript modules<span class=\"inline-flex not-prose\"></span></a>, you can use <code>next.config.mjs</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/**</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"> * </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: <code>next.config</code> with the <code>.cjs</code> or <code>.cts</code> extensions are currently <strong>not</strong> supported.</p>\n</blockquote>\n<h2 id=\"configuration-as-a-function\" data-docs-heading=\"\">Configuration as a Function<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#configuration-as-a-function\"><span></span></a></h2>\n<p>You can also use a function:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> (phase</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { defaultConfig }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /**</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   * </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"async-configuration\" data-docs-heading=\"\">Async Configuration<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#async-configuration\"><span></span></a></h3>\n<p>Since Next.js 12.1.0, you can use an async function:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> (phase</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { defaultConfig }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /**</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   * </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"phase\" data-docs-heading=\"\">Phase<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#phase\"><span></span></a></h3>\n<p><code>phase</code> is the current context in which the configuration is loaded. You can see the <a href=\"https://github.com/vercel/next.js/blob/5e6b008b561caf2710ab7be63320a3d549474a5b/packages/next/shared/lib/constants.ts#L19-L23\" rel=\"noopener noreferrer\" target=\"_blank\">available phases<span class=\"inline-flex not-prose\"></span></a>. Phases can be imported from <code>next/constants</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">PHASE_DEVELOPMENT_SERVER</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'next/constants'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> (phase</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> { defaultConfig }) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  if</span><span style=\"color:var(--shiki-color-text)\"> (phase </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-constant)\"> PHASE_DEVELOPMENT_SERVER</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      /* development only config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    /* config options for all phases except development here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"typescript\" data-docs-heading=\"\">TypeScript<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#typescript\"><span></span></a></h2>\n<p>If you are using TypeScript in your project, you can use <code>next.config.ts</code> to use TypeScript in your configuration:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>The commented lines are the place where you can put the configs allowed by <code>next.config.js</code>, which are <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/server/config-shared.ts\" rel=\"noopener noreferrer\" target=\"_blank\">defined in this file<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>However, none of the configs are required, and it's not necessary to understand what each config does. Instead, search for the features you need to enable or modify in this section and they will show you what to do.</p>\n<blockquote class=\"p-3 text-sm\">\n<p>Avoid using new JavaScript features not available in your target Node.js version. <code>next.config.js</code> will not be parsed by Webpack or Babel.</p>\n</blockquote>\n<p>This page documents all the available configuration options:</p>\n<h2 id=\"unit-testing-experimental\" data-docs-heading=\"\">Unit Testing (experimental)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#unit-testing-experimental\"><span></span></a></h2>\n<p>Starting in Next.js 15.1, the <code>next/experimental/testing/server</code> package contains utilities to help unit test <code>next.config.js</code> files.</p>\n<p>The <code>unstable_getResponseFromNextConfig</code> function runs the <a href=\"/docs/app/api-reference/config/next-config-js/headers\"><code>headers</code></a>, <a href=\"/docs/app/api-reference/config/next-config-js/redirects\"><code>redirects</code></a>, and <a href=\"/docs/app/api-reference/config/next-config-js/rewrites\"><code>rewrites</code></a> functions from <code>next.config.js</code> with the provided request information and returns <code>NextResponse</code> with the results of the routing.</p>\n<blockquote class=\"p-3 text-sm\">\n<p>The response from <code>unstable_getResponseFromNextConfig</code> only considers <code>next.config.js</code> fields and does not consider proxy or filesystem routes, so the result in production may be different than the unit test.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  getRedirectUrl</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  unstable_getResponseFromNextConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/experimental/testing/server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> response</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> unstable_getResponseFromNextConfig</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  url</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://nextjs.org/test'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    async</span><span style=\"color:var(--shiki-token-function)\"> redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-color-text)\"> [{ source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/test'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/test2'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-color-text)\"> }]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">})</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">expect</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">response</span><span style=\"color:var(--shiki-color-text)\">.status)</span><span style=\"color:var(--shiki-token-function)\">.toEqual</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">307</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">expect</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-function)\">getRedirectUrl</span><span style=\"color:var(--shiki-color-text)\">(response))</span><span style=\"color:var(--shiki-token-function)\">.toEqual</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'https://nextjs.org/test2'</span><span style=\"color:var(--shiki-color-text)\">)</span></span></code></pre></div></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/adapterPath\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">adapterPath</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure a custom adapter for Next.js to hook into the build process.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/allowedDevOrigins\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">allowedDevOrigins</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use `allowedDevOrigins` to configure additional origins that can request the dev server.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/appDir\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">appDir</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable the App Router to use layouts, streaming, and more.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/assetPrefix\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">assetPrefix</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the assetPrefix config option to configure your CDN.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/authInterrupts\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">authInterrupts</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the experimental `authInterrupts` configuration option to use `forbidden` and `unauthorized`.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/basePath\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">basePath</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use `basePath` to deploy a Next.js application under a sub-path of a domain.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheComponents</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the cacheComponents flag in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheHandlers</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure custom cache handlers for use cache directives in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheLife\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to set up cacheLife configurations in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/compress\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">compress</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js provides gzip compression to compress rendered content and static files, it only works with the server target. Learn more about it here.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/crossOrigin\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">crossOrigin</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use the `crossOrigin` option to add a crossOrigin tag on the `script` tags generated by `next/script`.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cssChunking\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cssChunking</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use the `cssChunking` option to control how CSS files are chunked in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/deploymentId\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">deploymentId</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure a deployment identifier used for version skew protection and cache busting.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/devIndicators\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">devIndicators</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configuration options for the on-screen indicator that gives context about the current route you're viewing during development.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/distDir\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">distDir</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Set a custom build directory to use instead of the default .next directory.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/env\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">env</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn to add and access environment variables in your Next.js application at build time.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/expireTime\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">expireTime</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Customize stale-while-revalidate expire time for ISR enabled pages.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/exportPathMap\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">exportPathMap</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Customize the pages that will be exported as HTML files when using `next export`.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/generateBuildId\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">generateBuildId</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure the build id, which is used to identify the current build in which your application is being served.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/generateEtags\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">generateEtags</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js will generate etags for every page by default. Learn more about how to disable etag generation here.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/headers\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">headers</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Add custom HTTP headers to your Next.js app.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/htmlLimitedBots\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">htmlLimitedBots</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Specify a list of user agents that should receive blocking metadata.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/httpAgentOptions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">httpAgentOptions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js will automatically use HTTP Keep-Alive by default. Learn more about how to disable HTTP Keep-Alive here.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/images\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">images</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Custom configuration for the next/image loader</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheHandler</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure the Next.js cache used for storing and revalidating data to use any external service like Redis, Memcached, or others.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/inlineCss\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">inlineCss</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable inline CSS support.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/instrumentationClientInject\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">instrumentationClientInject</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Inject additional client-side instrumentation modules before the user's `instrumentation-client.{js,ts}` file.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/logging\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">logging</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure logging behavior in the terminal when running Next.js in development mode, including fetch logging, incoming requests, and forwarding browser console logs to the terminal.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/mdxRs\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">mdxRs</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use the new Rust compiler to compile MDX files in the App Router.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/onDemandEntries\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">onDemandEntries</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure how Next.js will dispose and keep in memory pages created in development.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/optimizePackageImports\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">optimizePackageImports</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for optimizePackageImports Next.js Config Option</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/output\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">output</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js automatically traces which files are needed by each page to allow for easy deployment of your application. Learn how it works here.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/outputHashSalt\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">outputHashSalt</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to incorporate a custom salt string into content-addressed output filenames.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/pageExtensions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">pageExtensions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Extend the default page extensions used by Next.js when resolving pages in the Pages Router.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/partialPrefetching\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">partialPrefetching</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure the default link prefetch behavior to fetch only the static parts of each route.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/poweredByHeader\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">poweredByHeader</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Next.js will add the `x-powered-by` header by default. Learn to opt-out of it here.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/prefetchInlining\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">prefetchInlining</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Override how the App Router bundles small prefetch responses together.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/productionBrowserSourceMaps\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">productionBrowserSourceMaps</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enables browser source map generation during the production build.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/proxyClientMaxBodySize\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">proxyClientMaxBodySize</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure the maximum request body size when using proxy.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/reactCompiler\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">reactCompiler</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable the React Compiler to automatically optimize component rendering.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/reactMaxHeadersLength\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">reactMaxHeadersLength</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">The maximum length of the headers that are emitted by React and added to the response.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/reactStrictMode\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">reactStrictMode</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">The complete Next.js runtime is now Strict Mode-compliant, learn how to opt-in</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/redirects\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">redirects</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Add redirects to your Next.js app.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/rewrites\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">rewrites</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Add rewrites to your Next.js app.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/sassOptions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">sassOptions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Sass options.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/serverActions\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">serverActions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Server Actions behavior in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/serverComponentsHmrCache\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">serverComponentsHmrCache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure whether fetch responses in Server Components are cached across HMR refresh requests.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/serverExternalPackages\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">serverExternalPackages</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Opt-out specific dependencies from the Server Components bundling and use native Node.js `require`.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/staleTimes\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">staleTimes</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to override the invalidation time of the client cache.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/staticGeneration\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">staticGeneration*</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to configure static generation in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/supportsImmutableAssets\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">supportsImmutableAssets</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure support for immutable static assets</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/taint\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">taint</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable tainting Objects and Values.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/trailingSlash\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">trailingSlash</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Next.js pages to resolve with or without a trailing slash.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/transpilePackages\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">transpilePackages</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Transpile and bundle dependencies from monorepo workspace packages or `node_modules` libraries that ship TypeScript, JSX, or modern syntax.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopack\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopack</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Next.js with Turbopack-specific options</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackChunking\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopackChunking</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure how Turbopack splits your client-side JavaScript into chunks in production.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopackFileSystemCache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable and configure FileSystem Caching for Turbopack builds</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackIgnoreIssue\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopack.ignoreIssue</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Suppress specific Turbopack errors and warnings from the CLI output and error overlay.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackLocalPostcssConfig\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopackLocalPostcssConfig</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable per-directory PostCSS config resolution in Turbopack so that the config closest to each CSS file takes precedence over the project root config.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackMemoryEviction\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopackMemoryEviction</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to control Turbopack's memory eviction strategy for the persistent cache.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopackRustReactCompiler\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopackRustReactCompiler</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Use the native Rust port of the React Compiler with Turbopack instead of the Babel transform.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/typedRoutes\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">typedRoutes</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable support for statically typed links.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/typescript\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">typescript</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure how Next.js handles TypeScript errors during production builds and specify a custom tsconfig file.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/urlImports\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">urlImports</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Next.js to allow importing modules from external URLs.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/useLightningcss\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">useLightningcss</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable experimental support for Lightning CSS.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/useOffline\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">useOffline</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the experimental `useOffline` configuration option to detect connectivity and retry failed requests automatically.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/useTypeScriptCli\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">useTypeScriptCli</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Run the project-local TypeScript CLI for type checking during production builds.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/webpack\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">webpack</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to customize the webpack config used by Next.js</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/webVitalsAttribution\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">webVitalsAttribution</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the webVitalsAttribution option to pinpoint the source of Web Vitals issues.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/adapterPath",
    "title": "next.config.js: adapterPath | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">adapterPath</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 30, 2026</div><p>Next.js provides a built-in adapters API. It allows deployment platforms or build systems to integrate with the Next.js build process.</p>\n<p>For a full reference implementation, see the <a href=\"https://github.com/nextjs/adapter-vercel\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>nextjs/adapter-vercel</code><span class=\"inline-flex not-prose\"></span></a> adapter.</p>\n<h2 id=\"configuration\" data-docs-heading=\"\">Configuration<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#configuration\"><span></span></a></h2>\n<p>To use an adapter, specify the path to your adapter module in <code>adapterPath</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  adapterPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./my-adapter.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>Alternatively <code>NEXT_ADAPTER_PATH</code> can be set to enable zero-config usage in deployment platforms.</p>\n<h2 id=\"adapters\" data-docs-heading=\"\">Adapters<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#adapters\"><span></span></a></h2>\n<p>For full adapter implementation details, use the dedicated Adapters section:</p>\n<ul>\n<li><a href=\"/docs/app/api-reference/adapters/configuration\">Configuration</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/creating-an-adapter\">Creating an Adapter</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/api-reference\">API Reference</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/testing-adapters\">Testing Adapters</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/routing-with-next-routing\">Routing with <code>@next/routing</code></a></li>\n<li><a href=\"/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter\">Implementing PPR in an Adapter</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/runtime-integration\">Runtime Integration</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/invoking-entrypoints\">Invoking Entrypoints</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/output-types\">Output Types</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/routing-information\">Routing Information</a></li>\n<li><a href=\"/docs/app/api-reference/adapters/use-cases\">Use Cases</a></li>\n</ul>\n<h2 id=\"creating-an-adapter\" data-docs-heading=\"\">Creating an Adapter<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#creating-an-adapter\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/creating-an-adapter\">Creating an Adapter</a>.</p>\n<h2 id=\"api-reference\" data-docs-heading=\"\">API Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#api-reference\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/api-reference\">API Reference</a>.</p>\n<h2 id=\"testing-adapters\" data-docs-heading=\"\">Testing Adapters<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#testing-adapters\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/testing-adapters\">Testing Adapters</a>.</p>\n<h2 id=\"routing-with-nextrouting\" data-docs-heading=\"\">Routing with <code>@next/routing</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routing-with-nextrouting\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/routing-with-next-routing\">Routing with <code>@next/routing</code></a>.</p>\n<h2 id=\"implementing-ppr-in-an-adapter\" data-docs-heading=\"\">Implementing PPR in an Adapter<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#implementing-ppr-in-an-adapter\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter\">Implementing PPR in an Adapter</a>.</p>\n<h2 id=\"runtime-integration\" data-docs-heading=\"\">Runtime Integration<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#runtime-integration\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/runtime-integration\">Runtime Integration</a>.</p>\n<h2 id=\"invoking-entrypoints\" data-docs-heading=\"\">Invoking Entrypoints<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#invoking-entrypoints\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/invoking-entrypoints\">Invoking Entrypoints</a>.</p>\n<h2 id=\"output-types\" data-docs-heading=\"\">Output Types<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#output-types\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/output-types\">Output Types</a>.</p>\n<h2 id=\"routing-information\" data-docs-heading=\"\">Routing Information<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#routing-information\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/routing-information\">Routing Information</a>.</p>\n<h2 id=\"use-cases\" data-docs-heading=\"\">Use Cases<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#use-cases\"><span></span></a></h2>\n<p>See <a href=\"/docs/app/api-reference/adapters/use-cases\">Use Cases</a>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/allowedDevOrigins",
    "title": "next.config.js: allowedDevOrigins | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">allowedDevOrigins</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 17, 2026</div>\n<p>Next.js blocks cross-origin requests to dev-only assets and endpoints during development by default to prevent unauthorized access.</p>\n<p>To configure a Next.js application to allow requests from origins other than the hostname the server was initialized with (<code>localhost</code> by default), use the <code>allowedDevOrigins</code> config option.</p>\n<p><code>allowedDevOrigins</code> lets you set additional origins that can request the dev server in development mode. For example, to use <code>local-origin.dev</code> instead of only <code>localhost</code>, open <code>next.config.js</code> and add the <code>allowedDevOrigins</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  allowedDevOrigins</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'local-origin.dev'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.local-origin.dev'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/appDir",
    "title": "next.config.js: appDir | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">appDir<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-amber-900 selection:bg-amber-900 dark-theme:selection:bg-amber-500 dark-theme:selection:text-amber-1000 [&amp;_a:not([data-geist-button])]:text-amber-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-amber-100 bg-amber-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This is a legacy API and no longer recommended. It's still supported for backward compatibility.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This option is <strong>no longer</strong> needed as of Next.js 13.4. The App Router is now stable.</p>\n</blockquote>\n<p>The App Router (<a href=\"/docs/app\"><code>app</code> directory</a>) enables support for <a href=\"/docs/app/api-reference/file-conventions/layout\">layouts</a>, <a href=\"/docs/app/getting-started/server-and-client-components\">Server Components</a>, <a href=\"/docs/app/api-reference/file-conventions/loading\">streaming</a>, and <a href=\"/docs/app/getting-started/fetching-data\">colocated data fetching</a>.</p>\n<p>Using the <code>app</code> directory will automatically enable <a href=\"https://react.dev/reference/react/StrictMode\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">React Strict Mode<span class=\"inline-flex not-prose\"></span></a>. Learn how to <a href=\"/docs/app/guides/migrating/app-router-migration#migrating-from-pages-to-app\">incrementally adopt <code>app</code></a>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix",
    "title": "next.config.js: assetPrefix | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">assetPrefix</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Attention</strong>: <a href=\"/docs/app/getting-started/deploying\">Deploying to Vercel</a> automatically configures a global CDN for your Next.js project.\nYou do not need to manually setup an Asset Prefix.</p>\n</blockquote>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Next.js 9.5+ added support for a customizable <a href=\"/docs/app/api-reference/config/next-config-js/basePath\">Base Path</a>, which is better\nsuited for hosting your application on a sub-path like <code>/docs</code>.\nWe do not suggest you use a custom Asset Prefix for this use case.</p>\n</blockquote>\n<h2 id=\"set-up-a-cdn\" data-docs-heading=\"\">Set up a CDN<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#set-up-a-cdn\"><span></span></a></h2>\n<p>To set up a <a href=\"https://en.wikipedia.org/wiki/Content_delivery_network\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">CDN<span class=\"inline-flex not-prose\"></span></a>, you can set up an asset prefix and configure your CDN's origin to resolve to the domain that Next.js is hosted on.</p>\n<p>Open <code>next.config.mjs</code> and add the <code>assetPrefix</code> config based on the <a href=\"/docs/app/api-reference/config/next-config-js#async-configuration\">phase</a>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.mjs</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { PHASE_DEVELOPMENT_SERVER } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/constants'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> (phase) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> isDev</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> phase </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-constant)\"> PHASE_DEVELOPMENT_SERVER</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /**</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   * </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">   */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    assetPrefix</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> isDev </span><span style=\"color:var(--shiki-token-keyword)\">?</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://cdn.mydomain.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Next.js will automatically use your asset prefix for the JavaScript and CSS files it loads from the <code>/_next/</code> path (<code>.next/static/</code> folder). For example, with the above configuration, the following request for a JS chunk:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js</span></span></code></pre></div>\n<p>Would instead become:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>https://cdn.mydomain.com/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js</span></span></code></pre></div>\n<p>The exact configuration for uploading your files to a given CDN will depend on your CDN of choice. The only folder you need to host on your CDN is the contents of <code>.next/static/</code>, which should be uploaded as <code>_next/static/</code> as the above URL request indicates. <strong>Do not upload the rest of your <code>.next/</code> folder</strong>, as you should not expose your server code and other configuration to the public.</p>\n<p>While <code>assetPrefix</code> covers requests to <code>_next/static</code>, it does not influence the following paths:</p>\n<ul>\n<li>Files in the <a href=\"/docs/app/api-reference/file-conventions/public-folder\">public</a> folder; if you want to serve those assets over a CDN, you'll have to introduce the prefix yourself</li>\n</ul>\n</div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/authInterrupts",
    "title": "next.config.js: authInterrupts | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">authInterrupts<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently available in the canary channel and subject to change. Try it out by<!-- --> <a href=\"/docs/app/getting-started/upgrading#canary-version\">upgrading Next.js</a>, and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><p>The <code>authInterrupts</code> configuration option allows you to use <a href=\"/docs/app/api-reference/functions/forbidden\"><code>forbidden</code></a> and <a href=\"/docs/app/api-reference/functions/unauthorized\"><code>unauthorized</code></a> APIs in your application. While these functions are experimental, you must enable the <code>authInterrupts</code> option in your <code>next.config.js</code> file to use them:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    authInterrupts</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n</div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" data-docs-heading=\"\"></h2><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/forbidden\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">forbidden</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the forbidden function.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/unauthorized\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">unauthorized</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the unauthorized function.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/file-conventions/forbidden\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">forbidden.js</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API reference for the forbidden.js special file.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/file-conventions/unauthorized\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">unauthorized.js</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API reference for the unauthorized.js special file.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath",
    "title": "next.config.js: basePath | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">basePath</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>To deploy a Next.js application under a sub-path of a domain you can use the <code>basePath</code> config option.</p>\n<p><code>basePath</code> allows you to set a path prefix for the application. For example, to use <code>/docs</code> instead of <code>''</code> (an empty string, the default), open <code>next.config.js</code> and add the <code>basePath</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/docs'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This value must be set at build time and cannot be changed without re-building as the value is inlined in the client-side bundles.</p>\n</blockquote>\n<h3 id=\"links\" data-docs-heading=\"\">Links<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#links\"><span></span></a></h3>\n<p>When linking to other pages using <code>next/link</code> and <code>next/router</code> the <code>basePath</code> will be automatically applied.</p>\n<p>For example, using <code>/about</code> will automatically become <code>/docs/about</code> when <code>basePath</code> is set to <code>/docs</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> HomePage</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span><span style=\"color:var(--shiki-color-text)\">&gt;About Page&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Output html:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">a</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/docs/about\"</span><span style=\"color:var(--shiki-color-text)\">&gt;About Page&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">a</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<p>This makes sure that you don't have to change all links in your application when changing the <code>basePath</code> value.</p>\n<h3 id=\"images\" data-docs-heading=\"\">Images<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#images\"><span></span></a></h3>\n<p>When using the <a href=\"/docs/app/api-reference/components/image\"><code>next/image</code></a> component, you will need to add the <code>basePath</code> in front of <code>src</code>.</p>\n<!-- -->\n<p>For example, using <code>/docs/me.png</code> will properly serve your image when <code>basePath</code> is set to <code>/docs</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> Home</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;My Homepage&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/docs/me.png\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Picture of the author\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        width</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        height</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">500</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;Welcome to my homepage!&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> Home</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheComponents",
    "title": "next.config.js: cacheComponents | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">cacheComponents</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 22, 2026</div><p>Cache Components enables component and function-level caching using the <a href=\"/docs/app/api-reference/directives/use-cache\"><code>use cache</code></a> directive. Data fetching is dynamic by default, and you choose what to cache at the page, component, or function level. Next.js prerenders a static HTML shell that is served immediately while dynamic content streams in when ready, letting you mix static and dynamic content within a single route.</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>To enable the <code>cacheComponents</code> flag, set it to <code>true</code> in your <code>next.config.ts</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheComponents</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Cache Components requires the Node.js runtime. Migrate any routes that set the deprecated <code>runtime = 'edge'</code> export, and note that other server-side JavaScript runtimes are not guaranteed to work. See <a href=\"/docs/app/guides/migrating-to-cache-components#runtime--edge\">Migrating to Cache Components</a>.</p>\n</blockquote>\n<p>When <code>cacheComponents</code> is enabled, you can use the following cache functions and configurations:</p>\n<ul>\n<li>The <a href=\"/docs/app/api-reference/directives/use-cache\"><code>use cache</code> directive</a></li>\n<li>The <a href=\"/docs/app/api-reference/config/next-config-js/cacheLife\"><code>cacheLife</code> function</a> with <code>use cache</code></li>\n<li>The <a href=\"/docs/app/api-reference/functions/cacheTag\"><code>cacheTag</code> function</a></li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you used <code>experimental.useCache</code> or <code>experimental.dynamicIO</code>, migrate using the <a href=\"/docs/app/guides/upgrading/version-16#experimentaldynamicio-and-experimentalusecache\">Version 16 upgrade guide</a>. To migrate route segment configs and other caching patterns, see <a href=\"/docs/app/guides/migrating-to-cache-components\">Migrating to Cache Components</a>.</p>\n</blockquote>\n<p>Additionally, <code>cacheComponents</code> implements <strong><a href=\"/docs/app/glossary#partial-prerendering-ppr\">Partial Prerendering (PPR)</a></strong> as the default behavior in the App Router. This means the <code>experimental.ppr</code> configuration flag and the <code>experimental_ppr</code> route segment configuration are no longer necessary and have been removed.</p>\n<p>Read <a href=\"/docs/app/getting-started/caching#prerendering\">Prerendering</a> for how the static shell and streaming fit together.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you used experimental PPR in Next.js 15, refer to the <a href=\"/docs/app/guides/upgrading/version-16#partial-prerendering-ppr\">Partial Prerendering (PPR)</a> section of the Version 16 upgrade guide when migrating.</p>\n</blockquote>\n<h2 id=\"navigation-with-activity\" data-docs-heading=\"\">Navigation with Activity<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#navigation-with-activity\"><span></span></a></h2>\n<p>When <code>cacheComponents</code> is enabled, Next.js uses React's <a href=\"https://react.dev/reference/react/Activity\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>&lt;Activity&gt;</code><span class=\"inline-flex not-prose\"></span></a> component to preserve component state during client-side navigation.</p>\n<p>Rather than unmounting the previous route when you navigate away, Next.js sets the Activity mode to <a href=\"https://react.dev/reference/react/Activity#activity\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>\"hidden\"</code><span class=\"inline-flex not-prose\"></span></a>. This means:</p>\n<ul>\n<li>Component state is preserved when navigating between routes</li>\n<li>When you navigate back, the previous route reappears with its state intact</li>\n<li>Effects are cleaned up when a route is hidden, and recreated when it becomes visible again</li>\n</ul>\n<p>This behavior improves the navigation experience by maintaining UI state (form inputs, or expanded sections) when users navigate back and forth between routes.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Next.js uses heuristics to keep a few recently visited routes <code>\"hidden\"</code>, while older routes are removed from the DOM to prevent excessive growth.</p>\n</blockquote>\n<p>Some UI patterns behave differently when components stay mounted instead of unmounting. See the <a href=\"/docs/app/guides/preserving-ui-state\">Preserving UI state guide</a> for handling common patterns like dropdowns, dialogs, and testing.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Change</th></tr></thead><tbody><tr><td>16.0.0</td><td><code>cacheComponents</code> introduced. This flag controls the <code>ppr</code>, <code>useCache</code>, and <code>dynamicIO</code> flags as a single, unified configuration.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" data-docs-heading=\"\"></h2><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/getting-started/caching\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Caching</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to cache data and UI in Next.js</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/guides/incremental-static-regeneration-cache-components\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">ISR with Cache Components</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to prerender a subset of dynamic routes, serve App Shells for the rest, and upgrade them after the first visit.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache\" directive to cache data in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-remote\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: remote</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: remote\" directive for persistent, shared caching using remote cache handlers.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheHandlers",
    "title": "next.config.js: cacheHandlers | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">cacheHandlers</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 23, 2026</div><p>The <code>cacheHandlers</code> configuration allows you to define custom cache storage implementations for <a href=\"/docs/app/api-reference/directives/use-cache\"><code>'use cache'</code></a> and <a href=\"/docs/app/api-reference/directives/use-cache-remote\"><code>'use cache: remote'</code></a>. This enables you to store cached components and functions in external services or customize the caching behavior. <a href=\"/docs/app/api-reference/directives/use-cache-private\"><code>'use cache: private'</code></a> is not configurable.</p>\n<h2 id=\"when-to-use-custom-cache-handlers\" data-docs-heading=\"\">When to use custom cache handlers<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#when-to-use-custom-cache-handlers\"><span></span></a></h2>\n<p><strong>Most applications don't need custom cache handlers.</strong> The default in-memory cache works well in the typical use case.</p>\n<p>Custom cache handlers are for advanced scenarios where you need to either share cache across multiple instances or change where the cache is stored. For example, you can configure a custom <code>remote</code> handler for external storage (like a key-value store), then use <code>'use cache'</code> in your code for in-memory caching and <code>'use cache: remote'</code> for the external storage, allowing different caching strategies within the same application.</p>\n<p><strong>Sharing cache across instances</strong></p>\n<p>The default in-memory cache is isolated to each Next.js process. If you're running multiple servers or containers, each instance will have its own cache that isn't shared with others and is lost on restart.</p>\n<p>Custom handlers let you integrate with shared storage systems (like Redis, Memcached, or DynamoDB) that all your Next.js instances can access.</p>\n<p><strong>Changing storage type</strong></p>\n<p>You might want to store cache differently than the default in-memory approach. You can implement a custom handler to store cache on disk, in a database, or in an external caching service. Reasons include: persistence across restarts, reducing memory usage, or integrating with existing infrastructure.</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>To configure custom cache handlers:</p>\n<ol>\n<li>Define your cache handler in a separate file, see <a href=\"#examples\">examples</a> for implementation details.</li>\n<li>Reference the file path in your Next config file</li>\n</ol>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheHandlers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    default</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./cache-handlers/default-handler.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    remote</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./cache-handlers/remote-handler.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"handler-types\" data-docs-heading=\"\">Handler types<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#handler-types\"><span></span></a></h3>\n<ul>\n<li><strong><code>default</code></strong>: Used by the <code>'use cache'</code> directive</li>\n<li><strong><code>remote</code></strong>: Used by the <code>'use cache: remote'</code> directive</li>\n</ul>\n<p>If you don't configure <code>cacheHandlers</code>, Next.js uses an in-memory LRU (Least Recently Used) cache for both <code>default</code> and <code>remote</code>. You can view the <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/default.ts\" rel=\"noopener noreferrer\" target=\"_blank\">default implementation<span class=\"inline-flex not-prose\"></span></a> as a reference.</p>\n<p>You can also define additional named handlers (e.g., <code>sessions</code>, <code>analytics</code>) and reference them with <code>'use cache: &lt;name&gt;'</code>.</p>\n<p>Note that <code>'use cache: private'</code> does not use cache handlers and cannot be customized.</p>\n<h2 id=\"api-reference\" data-docs-heading=\"\">API Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#api-reference\"><span></span></a></h2>\n<p>A cache handler must implement the <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>CacheHandler</code><span class=\"inline-flex not-prose\"></span></a> interface with the following methods:</p>\n<h3 id=\"get\" data-docs-heading=\"\"><code>get()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#get\"><span></span></a></h3>\n<p>Retrieve a cache entry for the given cache key.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey: string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> softTags: string[]): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">CacheEntry </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span></span></code></pre></div>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>cacheKey</code></td><td><code>string</code></td><td>The unique key for the cache entry.</td></tr><tr><td><code>softTags</code></td><td><code>string[]</code></td><td>Implicit tags derived from the route path. See <a href=\"#soft-tags\">Soft Tags</a> for how to use them.</td></tr></tbody></table></div>\n<p>Returns a <code>CacheEntry</code> object if found, or <code>undefined</code> if not found or expired.</p>\n<p>Your <code>get</code> method should retrieve the cache entry from storage, check if it has expired based on the <code>revalidate</code> time, and return <code>undefined</code> for missing or expired entries.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> softTags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">!</span><span style=\"color:var(--shiki-color-text)\">entry) </span><span style=\"color:var(--shiki-token-keyword)\">return</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Check if expired</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> now</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> Date</span><span style=\"color:var(--shiki-token-function)\">.now</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (now </span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.timestamp </span><span style=\"color:var(--shiki-token-keyword)\">+</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.revalidate </span><span style=\"color:var(--shiki-token-keyword)\">*</span><span style=\"color:var(--shiki-token-constant)\"> 1000</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> entry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"set\" data-docs-heading=\"\"><code>set()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#set\"><span></span></a></h3>\n<p>Store a cache entry for the given cache key.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey: string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry: </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">CacheEntry</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-color-text)\">): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;void&gt;</span></span></code></pre></div>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>cacheKey</code></td><td><code>string</code></td><td>The unique key to store the entry under.</td></tr><tr><td><code>pendingEntry</code></td><td><code>Promise&lt;CacheEntry&gt;</code></td><td>A promise that resolves to the cache entry.</td></tr></tbody></table></div>\n<p>The entry may still be pending when this is called (i.e., its value stream may still be written to). Your handler should await the promise before processing the entry.</p>\n<p>Returns <code>Promise&lt;void&gt;</code>.</p>\n<p>Your <code>set</code> method must await the <code>pendingEntry</code> promise before storing it, since the cache entry may still be generating when this method is called. Once resolved, store the entry in your cache system.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Wait for the entry to be ready</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Store in your cache system</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    cache</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> entry)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"refreshtags\" data-docs-heading=\"\"><code>refreshTags()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#refreshtags\"><span></span></a></h3>\n<p>Called periodically before starting a new request to sync with external tag services.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">refreshTags</span><span style=\"color:var(--shiki-color-text)\">(): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;void&gt;</span></span></code></pre></div>\n<p>This is useful if you're coordinating cache invalidation across multiple instances or services. For in-memory caches, this can be a no-op.</p>\n<p>Returns <code>Promise&lt;void&gt;</code>.</p>\n<p>For in-memory caches, this can be a no-op. For distributed caches, use this to sync tag state from an external service or database before processing requests.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> refreshTags</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // For in-memory cache, no action needed</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // For distributed cache, sync tag state from external service</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"getexpiration\" data-docs-heading=\"\"><code>getExpiration()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#getexpiration\"><span></span></a></h3>\n<p>Get the maximum revalidation timestamp for a set of tags.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">getExpiration</span><span style=\"color:var(--shiki-color-text)\">(tags: string[]): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-color-text)\">number</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span></span></code></pre></div>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>tags</code></td><td><code>string[]</code></td><td>Array of tags to check expiration for.</td></tr></tbody></table></div>\n<p>Returns:</p>\n<ul>\n<li><code>0</code> if none of the tags were ever revalidated</li>\n<li>A timestamp (in milliseconds) representing the most recent revalidation</li>\n<li><code>Infinity</code> to indicate soft tags should be checked in the <code>get</code> method instead</li>\n</ul>\n<p>If you're not tracking tag revalidation timestamps, return <code>0</code>. Otherwise, find the most recent revalidation timestamp across all the provided tags. Return <code>Infinity</code> if you prefer to handle soft tag checking in the <code>get</code> method.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> getExpiration</span><span style=\"color:var(--shiki-color-text)\">(tags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Return 0 if not tracking tag revalidation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> 0</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Or return the most recent revalidation timestamp</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // return Math.max(...tags.map(tag =&gt; tagTimestamps.get(tag) || 0));</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"updatetags\" data-docs-heading=\"\"><code>updateTags()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#updatetags\"><span></span></a></h3>\n<p>Called when tags are revalidated or expired.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">updateTags</span><span style=\"color:var(--shiki-color-text)\">(tags: string[]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> durations</span><span style=\"color:var(--shiki-token-keyword)\">?:</span><span style=\"color:var(--shiki-color-text)\"> { expire?</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> number }): </span><span style=\"color:var(--shiki-token-constant)\">Promise</span><span style=\"color:var(--shiki-token-keyword)\">&lt;void&gt;</span></span></code></pre></div>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>tags</code></td><td><code>string[]</code></td><td>Array of tags to update.</td></tr><tr><td><code>durations</code></td><td><code>{ expire?: number }</code></td><td>Optional expiration duration in seconds.</td></tr></tbody></table></div>\n<p>Your handler should update its internal state to mark these tags as invalidated.</p>\n<p>Returns <code>Promise&lt;void&gt;</code>.</p>\n<p>When tags are revalidated, your handler should invalidate all cache entries that have any of those tags. Iterate through your cache and remove entries whose tags match the provided list.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> updateTags</span><span style=\"color:var(--shiki-color-text)\">(tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> durations) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Invalidate all cache entries with matching tags</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">key</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">] </span><span style=\"color:var(--shiki-token-keyword)\">of</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-function)\">.entries</span><span style=\"color:var(--shiki-color-text)\">()) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">entry</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">tags</span><span style=\"color:var(--shiki-token-function)\">.some</span><span style=\"color:var(--shiki-color-text)\">((tag) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> tags</span><span style=\"color:var(--shiki-token-function)\">.includes</span><span style=\"color:var(--shiki-color-text)\">(tag))) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        cache</span><span style=\"color:var(--shiki-token-function)\">.delete</span><span style=\"color:var(--shiki-color-text)\">(key)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"cacheentry-type\" data-docs-heading=\"\">CacheEntry Type<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cacheentry-type\"><span></span></a></h2>\n<p>The <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts\" rel=\"noopener noreferrer\" target=\"_blank\"><code>CacheEntry</code><span class=\"inline-flex not-prose\"></span></a> object has the following structure:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">interface</span><span style=\"color:var(--shiki-token-function)\"> CacheEntry</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> ReadableStream</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Uint8Array</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  tags</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">[]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  stale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  timestamp</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  expire</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  revalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> number</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Property</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>value</code></td><td><code>ReadableStream&lt;Uint8Array&gt;</code></td><td>The cached data as a stream.</td></tr><tr><td><code>tags</code></td><td><code>string[]</code></td><td>Cache tags (excluding soft tags).</td></tr><tr><td><code>stale</code></td><td><code>number</code></td><td>Duration in seconds for client-side staleness.</td></tr><tr><td><code>timestamp</code></td><td><code>number</code></td><td>When the entry was created (timestamp in milliseconds).</td></tr><tr><td><code>expire</code></td><td><code>number</code></td><td>How long the entry is allowed to be used (in seconds).</td></tr><tr><td><code>revalidate</code></td><td><code>number</code></td><td>How long until the entry should be revalidated (in seconds).</td></tr></tbody></table></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>The <code>value</code> is a <a href=\"https://developer.mozilla.org/docs/Web/API/ReadableStream\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>ReadableStream</code><span class=\"inline-flex not-prose\"></span></a>. Use <a href=\"https://developer.mozilla.org/docs/Web/API/ReadableStream/tee\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>.tee()</code><span class=\"inline-flex not-prose\"></span></a> if you need to read and store the stream data.</li>\n<li>If the stream errors with partial data, your handler must decide whether to keep the partial cache or discard it.</li>\n</ul>\n</blockquote>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"basic-in-memory-cache-handler\" data-docs-heading=\"\">Basic in-memory cache handler<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#basic-in-memory-cache-handler\"><span></span></a></h3>\n<p>Here's a minimal implementation using a <code>Map</code> for storage. This example demonstrates the core concepts, but for a production-ready implementation with LRU eviction, error handling, and tag management, see the <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/default.ts\" rel=\"noopener noreferrer\" target=\"_blank\">default cache handler<span class=\"inline-flex not-prose\"></span></a>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">cache-handlers/memory-handler.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> Map</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> pendingSets</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> Map</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> softTags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Wait for any pending set operation to complete</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> pendingPromise</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> pendingSets</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (pendingPromise) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      await</span><span style=\"color:var(--shiki-color-text)\"> pendingPromise</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">!</span><span style=\"color:var(--shiki-color-text)\">entry) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Check if entry has expired</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> now</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> Date</span><span style=\"color:var(--shiki-token-function)\">.now</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (now </span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.timestamp </span><span style=\"color:var(--shiki-token-keyword)\">+</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.revalidate </span><span style=\"color:var(--shiki-token-keyword)\">*</span><span style=\"color:var(--shiki-token-constant)\"> 1000</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      return</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> entry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Create a promise to track this set operation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    let</span><span style=\"color:var(--shiki-color-text)\"> resolvePending</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> pendingPromise</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-constant)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">((resolve) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      resolvePending </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\"> resolve</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    pendingSets</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> pendingPromise)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    try</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Wait for the entry to be ready</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Store the entry in the cache</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      cache</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> entry)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    } </span><span style=\"color:var(--shiki-token-keyword)\">finally</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      resolvePending</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      pendingSets</span><span style=\"color:var(--shiki-token-function)\">.delete</span><span style=\"color:var(--shiki-color-text)\">(cacheKey)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> refreshTags</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // No-op for in-memory cache</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> getExpiration</span><span style=\"color:var(--shiki-color-text)\">(tags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Return 0 to indicate no tags have been revalidated</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> 0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> updateTags</span><span style=\"color:var(--shiki-color-text)\">(tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> durations) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Implement tag-based invalidation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">key</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">] </span><span style=\"color:var(--shiki-token-keyword)\">of</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-function)\">.entries</span><span style=\"color:var(--shiki-color-text)\">()) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">entry</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">tags</span><span style=\"color:var(--shiki-token-function)\">.some</span><span style=\"color:var(--shiki-color-text)\">((tag) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> tags</span><span style=\"color:var(--shiki-token-function)\">.includes</span><span style=\"color:var(--shiki-color-text)\">(tag))) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        cache</span><span style=\"color:var(--shiki-token-function)\">.delete</span><span style=\"color:var(--shiki-color-text)\">(key)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"external-storage-pattern\" data-docs-heading=\"\">External storage pattern<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#external-storage-pattern\"><span></span></a></h3>\n<p>For durable storage like Redis or a database, you'll need to serialize the cache entries. Here's a simple Redis example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">cache-handlers/redis-handler.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">createClient</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'redis'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> createClient</span><span style=\"color:var(--shiki-color-text)\">({ url</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">REDIS_URL</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">client</span><span style=\"color:var(--shiki-token-function)\">.connect</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> softTags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Retrieve from Redis</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> stored</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(cacheKey)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">!</span><span style=\"color:var(--shiki-color-text)\">stored) </span><span style=\"color:var(--shiki-token-keyword)\">return</span><span style=\"color:var(--shiki-token-constant)\"> undefined</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Deserialize the entry</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> JSON</span><span style=\"color:var(--shiki-token-function)\">.parse</span><span style=\"color:var(--shiki-color-text)\">(stored)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Reconstruct the ReadableStream from stored data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> ReadableStream</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">        start</span><span style=\"color:var(--shiki-color-text)\">(controller) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          controller</span><span style=\"color:var(--shiki-token-function)\">.enqueue</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">Buffer</span><span style=\"color:var(--shiki-token-function)\">.from</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">data</span><span style=\"color:var(--shiki-color-text)\">.value</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'base64'</span><span style=\"color:var(--shiki-color-text)\">))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">          controller</span><span style=\"color:var(--shiki-token-function)\">.close</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      })</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      tags</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-color-text)\">.tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      stale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-color-text)\">.stale</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      timestamp</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-color-text)\">.timestamp</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      expire</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-color-text)\">.expire</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      revalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-color-text)\">.revalidate</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> set</span><span style=\"color:var(--shiki-color-text)\">(cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> pendingEntry</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Read the stream to get the data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> reader</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">value</span><span style=\"color:var(--shiki-token-function)\">.getReader</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> chunks</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> []</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    try</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      while</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">true</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">done</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> value</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> reader</span><span style=\"color:var(--shiki-token-function)\">.read</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">        if</span><span style=\"color:var(--shiki-color-text)\"> (done) </span><span style=\"color:var(--shiki-token-keyword)\">break</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        chunks</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">(value)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    } </span><span style=\"color:var(--shiki-token-keyword)\">finally</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      reader</span><span style=\"color:var(--shiki-token-function)\">.releaseLock</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Combine chunks and serialize for Redis storage</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> Buffer</span><span style=\"color:var(--shiki-token-function)\">.concat</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">chunks</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((chunk) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> Buffer</span><span style=\"color:var(--shiki-token-function)\">.from</span><span style=\"color:var(--shiki-color-text)\">(chunk)))</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    await</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      cacheKey</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      JSON</span><span style=\"color:var(--shiki-token-function)\">.stringify</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'base64'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        tags</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        stale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.stale</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        timestamp</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.timestamp</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        expire</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.expire</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        revalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.revalidate</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      })</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { EX</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> entry</span><span style=\"color:var(--shiki-color-text)\">.expire } </span><span style=\"color:var(--shiki-token-comment)\">// Use Redis TTL for automatic expiration</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> refreshTags</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // No-op for basic Redis implementation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Could sync with external tag service if needed</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> getExpiration</span><span style=\"color:var(--shiki-color-text)\">(tags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Return 0 to indicate no tags have been revalidated</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Could query Redis for tag expiration timestamps if tracking them</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> 0</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> updateTags</span><span style=\"color:var(--shiki-color-text)\">(tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> durations) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Implement tag-based invalidation if needed</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Could iterate over keys with matching tags and delete them</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"distributed-tag-coordination\" data-docs-heading=\"\">Distributed Tag Coordination<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#distributed-tag-coordination\"><span></span></a></h2>\n<p>When running multiple Next.js instances, tag invalidation must be coordinated across instances. The default in-memory handler only tracks tags locally, so calling <code>revalidateTag()</code> on one instance does not affect others.</p>\n<p>To coordinate tags across instances:</p>\n<ol>\n<li><strong><code>updateTags()</code></strong> is called when <code>revalidateTag()</code> is invoked. Your handler should write the invalidation timestamp to shared storage.</li>\n<li><strong><code>refreshTags()</code></strong> is called before each request. Your handler should read recent invalidation events from shared storage and update its local tag state.</li>\n<li><strong><code>getExpiration()</code></strong> returns the most recent revalidation timestamp across all provided tags. The default implementation returns <code>Math.max(...timestamps, 0)</code>.</li>\n</ol>\n<p>Here's an example using Redis for distributed tag coordination:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">cache-handlers/distributed-tags.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">createClient</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'redis'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> createClient</span><span style=\"color:var(--shiki-color-text)\">({ url</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">REDIS_URL</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">client</span><span style=\"color:var(--shiki-token-function)\">.connect</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Local cache of tag timestamps, synced via refreshTags</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> localTagTimestamps</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> Map</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // ... get() and set() methods ...</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> refreshTags</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Sync tag invalidation timestamps from Redis</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Using a dedicated set to track tag keys avoids scanning the keyspace</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> tagKeys</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-function)\">.sMembers</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'revalidated-tags'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">tagKeys</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-token-keyword)\"> &gt;</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      const</span><span style=\"color:var(--shiki-token-constant)\"> values</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-function)\">.mGet</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">tagKeys</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((k) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-string-expression)\"> `tag:</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">k</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">let</span><span style=\"color:var(--shiki-color-text)\"> i </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-color-text)\">; i </span><span style=\"color:var(--shiki-token-keyword)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\"> tagKeys</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-color-text)\">; i</span><span style=\"color:var(--shiki-token-keyword)\">++</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        localTagTimestamps</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(tagKeys[i]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-function)\"> Number</span><span style=\"color:var(--shiki-color-text)\">(values[i]))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> getExpiration</span><span style=\"color:var(--shiki-color-text)\">(tags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> timestamps</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> tags</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((tag) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> localTagTimestamps</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(tag) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> Math</span><span style=\"color:var(--shiki-token-function)\">.max</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">timestamps</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-function)\"> updateTags</span><span style=\"color:var(--shiki-color-text)\">(tags</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> durations) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> now</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> Date</span><span style=\"color:var(--shiki-token-function)\">.now</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> pipeline</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> client</span><span style=\"color:var(--shiki-token-function)\">.multi</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    for</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> tag</span><span style=\"color:var(--shiki-token-keyword)\"> of</span><span style=\"color:var(--shiki-color-text)\"> tags) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      pipeline</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`tag:</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">tag</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-function)\"> String</span><span style=\"color:var(--shiki-color-text)\">(now))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      pipeline</span><span style=\"color:var(--shiki-token-function)\">.sAdd</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'revalidated-tags'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> tag)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">      localTagTimestamps</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(tag</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> now)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    await</span><span style=\"color:var(--shiki-token-constant)\"> pipeline</span><span style=\"color:var(--shiki-token-function)\">.exec</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>For a full explanation of the tag architecture (including soft tags and multi-instance considerations), see <a href=\"/docs/app/guides/how-revalidation-works\">How Revalidation Works</a>.</p>\n<h2 id=\"soft-tags\" data-docs-heading=\"\">Soft Tags<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#soft-tags\"><span></span></a></h2>\n<p>Soft tags are implicit tags that Next.js automatically generates based on the route path. For example, the route <code>/blog/hello</code> generates soft tags for <code>/</code>, <code>/blog</code>, <code>/blog/hello</code>, and their corresponding layout entries. These tags are prefixed internally with <code>_N_T_</code>.</p>\n<p>Soft tags enable <a href=\"/docs/app/api-reference/functions/revalidatePath\"><code>revalidatePath()</code></a> to work through the same tag-based cache system. When <code>revalidatePath('/blog/hello')</code> is called, it invalidates all cache entries associated with that path's soft tags.</p>\n<p>In the cache handler API, soft tags are passed to the <a href=\"#get\"><code>get()</code></a> method as the <code>softTags</code> parameter. Your handler should check whether any soft tag has been invalidated (via <code>getExpiration()</code> or direct timestamp comparison) after the cache entry's <code>timestamp</code>. If a soft tag was invalidated more recently than the entry was created, the entry should be treated as stale.</p>\n<h2 id=\"handling-streams\" data-docs-heading=\"\">Handling Streams<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#handling-streams\"><span></span></a></h2>\n<p>The <code>CacheEntry.value</code> is a <a href=\"https://developer.mozilla.org/docs/Web/API/ReadableStream\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>ReadableStream&lt;Uint8Array&gt;</code><span class=\"inline-flex not-prose\"></span></a>. When implementing a cache handler that stores entries externally, keep in mind:</p>\n<ul>\n<li><strong>Use <code>.tee()</code></strong> if you need to both store and return the stream. One branch goes to storage, the other is returned to the caller.</li>\n<li><strong>Memory implications</strong>: large pages produce large cache entries. For S3-like storage backends, consider streaming directly to storage without buffering the entire entry in memory.</li>\n<li><strong>Partial writes</strong>: the stream may error partway through rendering. Your handler should decide whether to keep partial entries or discard them. Discarding is safer, as partial entries can produce incomplete pages.</li>\n</ul>\n<h2 id=\"error-handling\" data-docs-heading=\"\">Error Handling<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#error-handling\"><span></span></a></h2>\n<p>Cache operations should be implemented defensively:</p>\n<ul>\n<li><strong><code>set()</code> failure</strong>: the response is still served to the user because <code>set()</code> is called asynchronously after the response stream is already flowing. The cache entry is lost, and the next request triggers a fresh render.</li>\n<li><strong><code>get()</code> failure</strong>: your handler should catch internal errors and return <code>undefined</code> (the \"cache miss\" signal). The framework does not wrap <code>get()</code> in a try/catch, so an unhandled exception from <code>get()</code> will propagate as a render error.</li>\n<li><strong>Partial writes</strong>: if a cache entry is partially written and then read, the behavior is undefined. Use atomic writes or a write-then-rename pattern to avoid serving partial entries.</li>\n</ul>\n<h2 id=\"platform-support\" data-docs-heading=\"\">Platform Support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#platform-support\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Deployment Option</th><th class=\"min-w-[12ch]\">Supported</th></tr></thead><tbody><tr><td><a href=\"/docs/app/getting-started/deploying#nodejs-server\">Node.js server</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#docker\">Docker container</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#static-export\">Static export</a></td><td>No</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#adapters\">Adapters</a></td><td>Platform-specific</td></tr></tbody></table></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.0.0</code></td><td><code>cacheHandlers</code> introduced.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache\" directive to cache data in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-remote\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: remote</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: remote\" directive for persistent, shared caching using remote cache handlers.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-private\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: private</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: private\" directive to cache functions that access runtime request APIs.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheLife\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to set up cacheLife configurations in Next.js.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheLife",
    "title": "next.config.js: cacheLife | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">cacheLife</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 1, 2026</div><p>The <code>cacheLife</code> option allows you to define <strong>custom cache profiles</strong> when using the <a href=\"/docs/app/api-reference/functions/cacheLife\"><code>cacheLife</code></a> function inside components or functions, and within the scope of the <a href=\"/docs/app/api-reference/directives/use-cache\"><code>use cache</code> directive</a>.</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>To define a profile, enable the <a href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><code>cacheComponents</code> flag</a> and add the cache profile in the <code>cacheLife</code> object in the <code>next.config.js</code> file. For example, a <code>blog</code> profile:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheComponents</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheLife</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    blog</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      stale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 3600</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 1 hour</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      revalidate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 900</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 15 minutes</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      expire</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 86400</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 1 day</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>You can now use this custom <code>blog</code> configuration in your component or function as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/actions.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cacheLife } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getCachedData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cacheLife</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'blog'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>You can also override a built-in profile by defining one with the same name (<code>default</code>, <code>seconds</code>, <code>minutes</code>, <code>hours</code>, <code>days</code>, <code>weeks</code>, or <code>max</code>). See <a href=\"/docs/app/api-reference/functions/cacheLife#overriding-the-default-cache-profiles\">Overriding the default cache profiles</a>.</p>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<p>The configuration object has key values with the following format:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\"><strong>Property</strong></th><th class=\"min-w-[12ch]\"><strong>Value</strong></th><th class=\"min-w-[12ch]\"><strong>Description</strong></th><th class=\"min-w-[12ch]\"><strong>Requirement</strong></th></tr></thead><tbody><tr><td><code>stale</code></td><td><code>number</code></td><td>Duration the client should cache a value without checking the server.</td><td>Optional</td></tr><tr><td><code>revalidate</code></td><td><code>number</code></td><td>Frequency at which the cache should refresh on the server; stale values may be served while revalidating.</td><td>Optional</td></tr><tr><td><code>expire</code></td><td><code>number</code></td><td>Maximum duration for which a value can remain stale before switching to dynamic.</td><td>Optional - Must be longer than <code>revalidate</code></td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache\" directive to cache data in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheHandlers</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure custom cache handlers for use cache directives in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/cacheLife\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the cacheLife function to set the cache expiration time for a cached function or component.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/compress",
    "title": "next.config.js: compress | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">compress</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>By default, Next.js uses <code>gzip</code> to compress rendered content and static files when using <code>next start</code> or a custom server. This is an optimization for applications that do not have compression configured. If compression is <em>already</em> configured in your application via a custom server, Next.js will not add compression.</p>\n<p>You can check if compression is enabled and which algorithm is used by looking at the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Accept-Encoding</code><span class=\"inline-flex not-prose\"></span></a> (browser accepted options) and <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>Content-Encoding</code><span class=\"inline-flex not-prose\"></span></a> (currently used) headers in the response.</p>\n<h2 id=\"disabling-compression\" data-docs-heading=\"\">Disabling compression<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disabling-compression\"><span></span></a></h2>\n<p>To disable <strong>compression</strong>, set the <code>compress</code> config option to <code>false</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  compress</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>We <strong>do not recommend disabling compression</strong> unless you have compression configured on your server, as compression reduces bandwidth usage and improves the performance of your application. For example, you're using <a href=\"https://nginx.org/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">nginx<span class=\"inline-flex not-prose\"></span></a> and want to switch to <code>brotli</code>, set the <code>compress</code> option to <code>false</code> to allow nginx to handle compression.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/crossOrigin",
    "title": "next.config.js: crossOrigin | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">crossOrigin</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Use the <code>crossOrigin</code> option to add a <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>crossOrigin</code> attribute<span class=\"inline-flex not-prose\"></span></a> in all <code>&lt;script&gt;</code> tags generated by the <a href=\"/docs/app/guides/scripts\"><code>next/script</code></a> component<!-- --> <!-- -->, and define how cross-origin requests should be handled.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  crossOrigin</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'anonymous'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<ul>\n<li><code>'anonymous'</code>: Adds <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin#anonymous\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>crossOrigin=\"anonymous\"</code><span class=\"inline-flex not-prose\"></span></a> attribute.</li>\n<li><code>'use-credentials'</code>: Adds <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin#use-credentials\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>crossOrigin=\"use-credentials\"</code><span class=\"inline-flex not-prose\"></span></a>.</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/cssChunking",
    "title": "next.config.js: cssChunking | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">cssChunking<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 15, 2026</div><p>CSS Chunking is a strategy used to improve the performance of your web application by splitting and re-ordering CSS files into chunks. This lets a route load close to only the CSS it needs, instead of loading all the application's CSS at once.</p>\n<p>You can control how CSS files are chunked using the <code>experimental.cssChunking</code> option in your <code>next.config.js</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    cssChunking</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // default</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">satisfies</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<ul>\n<li><strong><code>true</code> (default)</strong> (<strong>webpack and Turbopack</strong>): Next.js will try to merge CSS files whenever possible, determining explicit and implicit dependencies between files from import order to reduce the number of chunks and therefore the number of requests.</li>\n<li><strong><code>false</code></strong> (<strong>webpack only</strong>): Next.js will not attempt to merge or re-order your CSS files.</li>\n<li><strong><code>'strict'</code></strong> (<strong>webpack only</strong>): Next.js will load CSS files in the correct order they are imported into your files, which can lead to more chunks and requests.</li>\n<li><strong><code>'graph'</code></strong> (<strong>Turbopack only</strong>): Next.js uses a cost-based graph algorithm to group CSS across your routes, balancing the bytes each route downloads and the requests it makes.</li>\n</ul>\n<h2 id=\"choosing-a-strategy\" data-docs-heading=\"\">Choosing a strategy<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#choosing-a-strategy\"><span></span></a></h2>\n<p>For most applications, the default (<code>true</code>) is the right choice in either bundler: it merges CSS to make fewer requests. Reach for another strategy only for a specific reason.</p>\n<p>In Turbopack, that reason is usually performance. Switch to <code>graph</code> to tune how CSS is shared across routes, cutting the unused CSS a route downloads at the cost of more requests (see <a href=\"#balancing-requests-and-grouping\">Balancing requests and grouping</a>).</p>\n<p>In webpack, that reason is usually correctness. Switch to <code>'strict'</code> if you run into unexpected CSS behavior. For example, if you import <code>a.css</code> and <code>b.css</code> in different files using a different <code>import</code> order (<code>a</code> before <code>b</code>, or <code>b</code> before <code>a</code>), <code>true</code> merges them in any order and assumes there are no dependencies between them; if <code>b.css</code> depends on <code>a.css</code>, <code>'strict'</code> prevents the merge and loads them in import order, at the cost of more chunks and requests. Use <code>false</code> to disable merging entirely.</p>\n<h2 id=\"debugging-what-a-route-actually-uses\" data-docs-heading=\"\">Debugging what a route actually uses<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#debugging-what-a-route-actually-uses\"><span></span></a></h2>\n<p>While some unused CSS is acceptable, and most apps do not need to change anything, it is worth keeping render-blocking CSS in check. <a href=\"https://developer.chrome.com/docs/lighthouse/performance/unused-css-rules\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Lighthouse<span class=\"inline-flex not-prose\"></span></a> flags this as a <strong>Reduce unused CSS</strong> opportunity with an estimated saving, and Chrome DevTools shows it per stylesheet in its <a href=\"https://developer.chrome.com/docs/devtools/coverage\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Coverage panel<span class=\"inline-flex not-prose\"></span></a>, where a usage bar shows each stylesheet's applied CSS in green and unused CSS in gray.</p>\n<p>When reading the report, watch out for styles that only apply on interaction, such as <code>:hover</code>, <code>:focus</code>, or classes toggled by JavaScript for menus and modals, since Coverage counts them as unused until you trigger them.</p>\n<p>The source of this unused CSS is one of two things. Either it is dead CSS in a stylesheet your route imports, which you fix in your source by removing the unused rules or moving them into a stylesheet only the routes that use them import (<a href=\"/docs/app/getting-started/css#css-modules\">CSS Modules</a> make this natural by scoping styles to the component that imports them).</p>\n<p>Or the bundler merged another stylesheet into a shared chunk that your route loads. That is governed by your <a href=\"#choosing-a-strategy\">chunking strategy</a>. In Turbopack, <a href=\"#balancing-requests-and-grouping\"><code>graph</code> mode</a> lets you fine-tune how aggressively CSS merges.</p>\n<h2 id=\"balancing-requests-and-grouping\" data-docs-heading=\"\">Balancing requests and grouping<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#balancing-requests-and-grouping\"><span></span></a></h2>\n<p>The <code>graph</code> strategy groups CSS into shared chunks to cut requests. Turn it on with the string form, which uses the default tuning:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    cssChunking</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'graph'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">satisfies</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>To shift that balance, pass an object instead. Both <code>requestCost</code> and <code>weightDistribution</code> are optional, so include only the one you want to change:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    cssChunking</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'graph'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      requestCost</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 100000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      weightDistribution</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 0.1</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">satisfies</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<ul>\n<li><strong><code>requestCost</code></strong> (default <code>20000</code>): the estimated cost, in bytes, of each additional CSS request. Larger values bias toward fewer, larger shared chunks, and fewer requests overall.</li>\n<li><strong><code>weightDistribution</code></strong> (default <code>0.1</code>): controls how a shared chunk's cost is distributed across the routes that load it, weighted by how much CSS each route imports. <code>0</code> weights every route equally; higher values give more weight to routes that import less CSS, so the algorithm prioritizes routes with less CSS, assuming extra CSS is less noticeable on large routes.</li>\n</ul>\n<h3 id=\"how-graph-decides-what-to-merge\" data-docs-heading=\"\">How <code>graph</code> decides what to merge<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-graph-decides-what-to-merge\"><span></span></a></h3>\n<p>Merging CSS into shared chunks is what the default (<code>true</code>) already does; <code>graph</code> just lets you control where it draws the line between merging and splitting.</p>\n<p>Take two routes that share a stylesheet:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>/a → [shared.css, only-a.css]</span></span>\n<span class=\"line\" data-line=\"\"><span>/b → [shared.css]</span></span></code></pre></div>\n<p>Here, <code>/b</code> never imports <code>only-a.css</code>, so there is one decision to make: keep <code>only-a.css</code> in the shared chunk, or give it its own.</p>\n<p>Keeping it merged lets <code>/a</code> load all its CSS in a single request. The cost is that <code>/b</code>, which also loads that shared chunk, now downloads <code>only-a.css</code> even though it never imported it.</p>\n<p>Splitting it out spares <code>/b</code> those bytes, but now <code>/a</code> has to make two requests. The default picks between these with a fixed heuristic.</p>\n<p>The <code>requestCost</code> option is how <code>graph</code> prices that trade: the amount of un-imported CSS worth one extra request. It keeps <code>only-a.css</code> merged while <code>only-a.css</code> stays well under <code>requestCost</code>, and splits it out once it grows large enough to outweigh the request.</p>\n<p>What drives the decision is the size of the un-imported CSS a merge would push onto a route, much more than the size of the shared chunk it joins. With the default <code>requestCost</code> of about 20 KB, <code>only-a.css</code> would have to exceed roughly that size before it earns its own chunk, so small stylesheets stay merged.</p>\n<details><summary>Graph algorithm overview</summary><p>At a high level, the algorithm works with individual CSS files. It starts from the ordered list of CSS each route imports:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>/dashboard  → [reset.css, theme.css, layout.css, dashboard.css]</span></span>\n<span class=\"line\" data-line=\"\"><span>/settings   → [reset.css, theme.css, layout.css, settings.css]</span></span>\n<span class=\"line\" data-line=\"\"><span>/login      → [reset.css, login.css]</span></span></code></pre></div><p>From these it builds a weighted graph where two CSS files get a heavier edge the more routes import them together in the same order. It flattens that graph into a single line that keeps frequently-paired files adjacent, then places <em>cuts</em> that divide the line into chunks, for example:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>reset theme layout │ dashboard │ settings │ login</span></span>\n<span class=\"line\" data-line=\"\"><span>└──── chunk 1 ────┘   chunk 2     chunk 3    chunk 4</span></span></code></pre></div><p>A route loads every chunk holding a file it imports, so <code>/dashboard</code> loads chunks 1 and 2 while <code>/login</code> loads chunks 1 and 4.</p><p>The algorithm chooses where to split chunks to minimize the total download cost across all routes, balancing bytes and requests. It optimizes that total, not each route on its own, so a route can end up carrying some CSS it never imported when that keeps the overall cost down. The two options control the weighing:</p><ul>\n<li><strong><code>requestCost</code></strong>: <code>reset.css</code>, <code>theme.css</code>, and <code>layout.css</code> share one chunk, so a route that needs them makes one request instead of three. <code>requestCost</code> is the price of a request in bytes: raise it and the algorithm merges more like this, trading larger downloads for fewer requests; lower it toward <code>0</code> and it splits chunks apart, so routes download closer to only what they import but make more requests.</li>\n<li><strong><code>weightDistribution</code></strong>: <code>/login</code> needs only <code>reset.css</code> from chunk 1 but downloads <code>theme.css</code> and <code>layout.css</code> too, since they share that chunk. This option decides how much the algorithm minds that. At <code>0</code>, <code>/login</code> and <code>/dashboard</code> count equally, so it lets the extra ride along; raise it and routes that import little CSS, like <code>/login</code>, count for more, so the algorithm works to spare them CSS they never imported, at the cost of more requests overall.</li>\n</ul></details></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/deploymentId",
    "title": "next.config.js: deploymentId | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">deploymentId</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 8, 2026</div>\n<p>The <code>deploymentId</code> option allows you to set an identifier for your deployment. This identifier is used for <a href=\"/docs/app/guides/self-hosting#version-skew\">version skew</a> protection and cache busting during rolling deployments.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  deploymentId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my-deployment-id'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also set the deployment ID using the <code>NEXT_DEPLOYMENT_ID</code> environment variable:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NEXT_DEPLOYMENT_ID</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">my-deployment-id</span><span style=\"color:var(--shiki-token-function)\"> next</span><span style=\"color:var(--shiki-token-string)\"> build</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> If both are set, the <code>deploymentId</code> value in <code>next.config.js</code> takes precedence over the <code>NEXT_DEPLOYMENT_ID</code> environment variable.</p>\n</blockquote>\n<h2 id=\"how-it-works\" data-docs-heading=\"\">How it works<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-it-works\"><span></span></a></h2>\n<p>When a <code>deploymentId</code> is configured, Next.js:</p>\n<ol>\n<li>Appends <code>?dpl=&lt;deploymentId&gt;</code> to static asset URLs (JavaScript, CSS, images)</li>\n<li>Adds an <code>x-deployment-id</code> header to client-side navigation requests</li>\n<li>Adds an <code>x-nextjs-deployment-id</code> header to navigation responses</li>\n<li>Injects a <code>data-dpl-id</code> attribute on the <code>&lt;html&gt;</code> element</li>\n<li>Includes the <code>deploymentId</code> in the <a href=\"/docs/app/api-reference/directives/use-cache#cache-keys\"><code>'use cache'</code> cache key</a>, invalidating cache entries when the deployment ID changes</li>\n</ol>\n<p>When the client detects a mismatch between its deployment ID and the server's (via the response header), it triggers a hard navigation (full page reload) instead of a client-side navigation. This ensures users always receive assets <!-- -->and Server Functions<!-- --> from a consistent deployment version.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> Next.js does not read the <code>?dpl=</code> query parameter on incoming requests. The query parameter is for cache busting (ensuring browsers and CDNs fetch fresh assets), not for routing. If you need version-aware routing, consult your hosting provider or CDN's documentation for implementing deployment-based routing.</p>\n</blockquote>\n<h2 id=\"use-cases\" data-docs-heading=\"\">Use cases<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#use-cases\"><span></span></a></h2>\n<h3 id=\"rolling-deployments\" data-docs-heading=\"\">Rolling deployments<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#rolling-deployments\"><span></span></a></h3>\n<p>During a rolling deployment, some server instances may be running the new version while others are still running the old version. Without a deployment ID, users might receive a mix of old and new assets, causing errors.</p>\n<p>Setting a consistent <code>deploymentId</code> per deployment ensures:</p>\n<ul>\n<li>Clients always request assets from a matching deployment version</li>\n<li>Mismatches trigger a full reload to fetch the correct assets</li>\n<li>Server Functions work correctly across deployment boundaries</li>\n</ul>\n<!-- -->\n<h3 id=\"multi-server-environments\" data-docs-heading=\"\">Multi-server environments<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#multi-server-environments\"><span></span></a></h3>\n<p>When running multiple instances of your Next.js application behind a load balancer, all instances for the same deployment should use the same <code>deploymentId</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  deploymentId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">DEPLOYMENT_VERSION</span><span style=\"color:var(--shiki-token-keyword)\"> ||</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">GIT_SHA</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v14.1.4</code></td><td><code>deploymentId</code> stabilized as top-level config option.</td></tr><tr><td><code>v13.4.10</code></td><td><code>experimental.deploymentId</code> introduced.</td></tr></tbody></table></div>\n<h2 id=\"related\" data-docs-heading=\"\">Related<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#related\"><span></span></a></h2>\n<ul>\n<li><a href=\"/docs/app/guides/self-hosting#version-skew\">Self-Hosting - Version Skew</a></li>\n<li><a href=\"/docs/app/api-reference/config/next-config-js/generateBuildId\">generateBuildId</a></li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/devIndicators",
    "title": "next.config.js: devIndicators | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">devIndicators</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 12, 2026</div><p><code>devIndicators</code> allows you to configure the on-screen indicator that gives context about the current route you're viewing during development.</p>\n<p>Open <code>next.config.ts</code> and set <code>position</code> to choose where the indicator renders. The default is <code>bottom-left</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  devIndicators</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    position</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'bottom-right'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>To hide the indicator entirely, set <code>devIndicators</code> to <code>false</code>. Next.js will still surface any compile or runtime errors that were encountered.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  devIndicators</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<h2 id=\"troubleshooting\" data-docs-heading=\"\">Troubleshooting<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#troubleshooting\"><span></span></a></h2>\n<h3 id=\"indicator-not-marking-a-route-as-static\" data-docs-heading=\"\">Indicator not marking a route as static<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#indicator-not-marking-a-route-as-static\"><span></span></a></h3>\n<p>If you expect a route to be static and the indicator has marked it as dynamic, it's likely the route has opted out of prerendering.</p>\n<p>You can confirm if a route is <a href=\"/docs/app/glossary#prerendering\">prerendered</a> or <a href=\"/docs/app/glossary#dynamic-rendering\">dynamically rendered</a> by building your application using <code>next build --debug</code>, and checking the output in your terminal. Static (or prerendered) routes will display a <code>○</code> symbol, whereas dynamic routes will display a <code>ƒ</code> symbol. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Build Output</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\"> (app)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">┌</span><span style=\"color:var(--shiki-token-string)\"> ○</span><span style=\"color:var(--shiki-token-string)\"> /_not-found</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">└</span><span style=\"color:var(--shiki-token-string)\"> ƒ</span><span style=\"color:var(--shiki-token-string)\"> /products/[id]</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">○</span><span style=\"color:var(--shiki-color-text)\">  (Static)   prerendered as static content</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">ƒ</span><span style=\"color:var(--shiki-color-text)\">  (Dynamic)  server-rendered on demand</span></span></code></pre></div>\n<p>There are two reasons a route might opt out of prerendering:</p><ul>\n<li>The presence of <a href=\"/docs/app/glossary#request-time-apis\">Request-time APIs</a> which rely on request information.</li>\n<li>An <a href=\"/docs/app/getting-started/fetching-data\">uncached data request</a>, like a call to an ORM or database driver.</li>\n</ul><p>Check your route for any of these conditions, and if you are not able to statically render the route, then consider using <a href=\"/docs/app/api-reference/file-conventions/loading\"><code>loading.js</code></a> or <a href=\"https://react.dev/reference/react/Suspense\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>&lt;Suspense /&gt;</code><span class=\"inline-flex not-prose\"></span></a> to leverage <a href=\"/docs/app/getting-started/linking-and-navigating#streaming\">streaming</a>.</p>\n<!-- -->\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.0.0</code></td><td><code>appIsrStatus</code>, <code>buildActivity</code>, and <code>buildActivityPosition</code> options have been removed.</td></tr><tr><td><code>v15.2.0</code></td><td>Improved on-screen indicator with new <code>position</code> option. <code>appIsrStatus</code>, <code>buildActivity</code>, and <code>buildActivityPosition</code> options have been deprecated.</td></tr><tr><td><code>v15.0.0</code></td><td>Static on-screen indicator added with <code>appIsrStatus</code> option.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/distDir",
    "title": "next.config.js: distDir | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">distDir</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>You can specify a name to use for a custom build directory to use instead of <code>.next</code>.</p>\n<p>Open <code>next.config.js</code> and add the <code>distDir</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  distDir</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'build'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Now if you run <code>next build</code> Next.js will use <code>build</code> instead of the default <code>.next</code> folder.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><code>distDir</code> <strong>should not</strong> leave your project directory. For example, <code>../build</code> is an <strong>invalid</strong> directory.</p>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/env",
    "title": "next.config.js: env | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">env<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-amber-900 selection:bg-amber-900 dark-theme:selection:bg-amber-500 dark-theme:selection:text-amber-1000 [&amp;_a:not([data-geist-button])]:text-amber-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-amber-100 bg-amber-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This is a legacy API and no longer recommended. It's still supported for backward compatibility.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<blockquote class=\"p-3 text-sm\">\n<p>Since the release of <a href=\"https://nextjs.org/blog/next-9-4\" rel=\"noopener noreferrer\" target=\"_blank\">Next.js 9.4<span class=\"inline-flex not-prose\"></span></a> we now have a more intuitive and ergonomic experience for <a href=\"/docs/app/guides/environment-variables\">adding environment variables</a>. Give it a try!</p>\n</blockquote>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: environment variables specified in this way will <strong>always</strong> be included in the JavaScript bundle, prefixing the environment variable name with <code>NEXT_PUBLIC_</code> only has an effect when specifying them <a href=\"/docs/app/guides/environment-variables\">through the environment or .env files</a>.</p>\n</blockquote>\n<!-- -->\n<p>To add environment variables to the JavaScript bundle, open <code>next.config.js</code> and add the <code>env</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  env</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    customKey</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my-value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Now you can access <code>process.env.customKey</code> in your code. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;The value of customKey is: {</span><span style=\"color:var(--shiki-token-constant)\">process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.customKey}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> Page</span></span></code></pre></div>\n<p>Next.js will replace <code>process.env.customKey</code> with <code>'my-value'</code> at build time. Trying to destructure <code>process.env</code> variables won't work due to the nature of webpack <a href=\"https://webpack.js.org/plugins/define-plugin/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">DefinePlugin<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>For example, the following line:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;The value of customKey is: {</span><span style=\"color:var(--shiki-token-constant)\">process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.customKey}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div>\n<p>Will end up being:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;The value of customKey is: {</span><span style=\"color:var(--shiki-token-string-expression)\">'my-value'</span><span style=\"color:var(--shiki-color-text)\">}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/expireTime",
    "title": "next.config.js: expireTime | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">expireTime</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>You can specify a custom <code>stale-while-revalidate</code> expire time for CDNs to consume in the <code>Cache-Control</code> header for ISR enabled pages.</p>\n<p>Open <code>next.config.js</code> and add the <code>expireTime</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // one hour in seconds</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  expireTime</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 3600</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Now when sending the <code>Cache-Control</code> header the expire time will be calculated depending on the specific revalidate period.</p>\n<p>For example, if you have a revalidate of 15 minutes on a path and the expire time is one hour the generated <code>Cache-Control</code> header will be <code>s-maxage=900, stale-while-revalidate=2700</code> so that it can stay stale for 15 minutes less than the configured expire time.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/exportPathMap",
    "title": "next.config.js: exportPathMap | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">exportPathMap<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-amber-900 selection:bg-amber-900 dark-theme:selection:bg-amber-500 dark-theme:selection:text-amber-1000 [&amp;_a:not([data-geist-button])]:text-amber-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-amber-100 bg-amber-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This is a legacy API and no longer recommended. It's still supported for backward compatibility.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<blockquote class=\"p-3 text-sm\">\n<p>This feature is exclusive to <code>next export</code> and currently <strong>deprecated</strong> in favor of <code>getStaticPaths</code> with <code>pages</code> or <code>generateStaticParams</code> with <code>app</code>.</p>\n</blockquote>\n<p><code>exportPathMap</code> allows you to specify a mapping of request paths to page destinations, to be used during export. Paths defined in <code>exportPathMap</code> will also be available when using <a href=\"/docs/app/api-reference/cli/next#next-dev-options\"><code>next dev</code></a>.</p>\n<p>Let's start with an example, to create a custom <code>exportPathMap</code> for an app with the following pages:</p>\n<ul>\n<li><code>pages/index.js</code></li>\n<li><code>pages/about.js</code></li>\n<li><code>pages/post.js</code></li>\n</ul>\n<p>Open <code>next.config.js</code> and add the following <code>exportPathMap</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  exportPathMap</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    defaultPathMap</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    { dev</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> dir</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> outDir</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> distDir</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> buildId }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '/'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { page</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '/about'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { page</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '/p/hello-nextjs'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { page</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> query</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'hello-nextjs'</span><span style=\"color:var(--shiki-color-text)\"> } }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '/p/learn-nextjs'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { page</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> query</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'learn-nextjs'</span><span style=\"color:var(--shiki-color-text)\"> } }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '/p/deploy-nextjs'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { page</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> query</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'deploy-nextjs'</span><span style=\"color:var(--shiki-color-text)\"> } }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: the <code>query</code> field in <code>exportPathMap</code> cannot be used with <a href=\"/docs/pages/building-your-application/rendering/automatic-static-optimization\">automatically statically optimized pages</a> or <a href=\"/docs/pages/building-your-application/data-fetching/get-static-props\"><code>getStaticProps</code> pages</a> as they are rendered to HTML files at build-time and additional query information cannot be provided during <code>next export</code>.</p>\n</blockquote>\n<p>The pages will then be exported as HTML files, for example, <code>/about</code> will become <code>/about.html</code>.</p>\n<p><code>exportPathMap</code> is an <code>async</code> function that receives 2 arguments: the first one is <code>defaultPathMap</code>, which is the default map used by Next.js. The second argument is an object with:</p>\n<ul>\n<li><code>dev</code> - <code>true</code> when <code>exportPathMap</code> is being called in development. <code>false</code> when running <code>next export</code>. In development <code>exportPathMap</code> is used to define routes.</li>\n<li><code>dir</code> - Absolute path to the project directory</li>\n<li><code>outDir</code> - Absolute path to the <code>out/</code> directory (<a href=\"#customizing-the-output-directory\">configurable with <code>-o</code></a>). When <code>dev</code> is <code>true</code> the value of <code>outDir</code> will be <code>null</code>.</li>\n<li><code>distDir</code> - Absolute path to the <code>.next/</code> directory (configurable with the <a href=\"/docs/pages/api-reference/config/next-config-js/distDir\"><code>distDir</code></a> config)</li>\n<li><code>buildId</code> - The generated build id</li>\n</ul>\n<p>The returned object is a map of pages where the <code>key</code> is the <code>pathname</code> and the <code>value</code> is an object that accepts the following fields:</p>\n<ul>\n<li><code>page</code>: <code>String</code> - the page inside the <code>pages</code> directory to render</li>\n<li><code>query</code>: <code>Object</code> - the <code>query</code> object passed to <code>getInitialProps</code> when prerendering. Defaults to <code>{}</code></li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p>The exported <code>pathname</code> can also be a filename (for example, <code>/readme.md</code>), but you may need to set the <code>Content-Type</code> header to <code>text/html</code> when serving its content if it is different than <code>.html</code>.</p>\n</blockquote>\n<h2 id=\"adding-a-trailing-slash\" data-docs-heading=\"\">Adding a trailing slash<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#adding-a-trailing-slash\"><span></span></a></h2>\n<p>It is possible to configure Next.js to export pages as <code>index.html</code> files and require trailing slashes, <code>/about</code> becomes <code>/about/index.html</code> and is routable via <code>/about/</code>. This was the default behavior prior to Next.js 9.</p>\n<p>To switch back and add a trailing slash, open <code>next.config.js</code> and enable the <code>trailingSlash</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  trailingSlash</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"customizing-the-output-directory\" data-docs-heading=\"\">Customizing the output directory<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#customizing-the-output-directory\"><span></span></a></h2>\n<p><a href=\"/docs/app/guides/static-exports\"><code>next export</code></a> will use <code>out</code> as the default output directory, you can customize this using the <code>-o</code> argument, like so:</p>\n<!-- -->\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">next</span><span style=\"color:var(--shiki-token-string)\"> export</span><span style=\"color:var(--shiki-token-string)\"> -o</span><span style=\"color:var(--shiki-token-string)\"> outdir</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning</strong>: Using <code>exportPathMap</code> is deprecated and is overridden by <code>getStaticPaths</code> inside <code>pages</code>. We don't recommend using them together.</p>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/generateBuildId",
    "title": "next.config.js: generateBuildId | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">generateBuildId</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Next.js generates an ID during <code>next build</code> to identify which version of your application is being served. The same build should be used and boot up multiple containers.</p>\n<p>If you are rebuilding for each stage of your environment, you will need to generate a consistent build ID to use between containers. Use the <code>generateBuildId</code> command in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  generateBuildId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // This could be anything, using the latest git hash</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">GIT_HASH</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/generateEtags",
    "title": "next.config.js: generateEtags | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">generateEtags</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Next.js will generate <a href=\"https://en.wikipedia.org/wiki/HTTP_ETag\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">etags<span class=\"inline-flex not-prose\"></span></a> for every page by default. You may want to disable etag generation for HTML pages depending on your cache strategy.</p>\n<p>Open <code>next.config.js</code> and disable the <code>generateEtags</code> option:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  generateEtags</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/headers",
    "title": "next.config.js: headers | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">headers</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 30, 2026</div>\n<p>Headers allow you to set custom HTTP headers on the response to an incoming request on a given path.</p>\n<p>To set custom HTTP headers you can use the <code>headers</code> key in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-custom-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my custom header value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-another-custom-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my other custom header value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>headers</code> can be defined as a synchronous or async function. It should return, or resolve to, an array of objects with <code>source</code> and <code>headers</code> properties:</p>\n<ul>\n<li><code>source</code> is the incoming request path pattern.</li>\n<li><code>headers</code> is an array of response header objects, with <code>key</code> and <code>value</code> properties.</li>\n<li><code>basePath</code>: <code>false</code> or <code>undefined</code> - if false the basePath won't be included when matching, can be used for external rewrites only.</li>\n<li><code>locale</code>: <code>false</code> or <code>undefined</code> - whether the locale should not be included when matching.</li>\n<li><code>has</code> is an array of <a href=\"#header-cookie-and-query-matching\">has objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n<li><code>missing</code> is an array of <a href=\"#header-cookie-and-query-matching\">missing objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n</ul>\n<p>Headers are checked before the filesystem which includes pages and <code>/public</code> files.</p>\n<h2 id=\"header-overriding-behavior\" data-docs-heading=\"\">Header Overriding Behavior<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#header-overriding-behavior\"><span></span></a></h2>\n<p>If two headers match the same path and set the same header key, the last header key will override the first. Using the below headers, the path <code>/hello</code> will result in the header <code>x-hello</code> being <code>world</code> due to the last header value set being <code>world</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'there'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"path-matching\" data-docs-heading=\"\">Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#path-matching\"><span></span></a></h2>\n<p>Path matches are allowed, for example <code>/blog/:slug</code> will match <code>/blog/first-post</code> (no nested paths):</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the value</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-slug-:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the key</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my other custom header value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The pattern <code>/blog/:slug</code> matches <code>/blog/first-post</code> and <code>/blog/post-1</code> but not a nested path like <code>/blog/a/b</code>. Patterns are anchored to the start, <code>/blog/:slug</code> will not match <code>/archive/blog/first-post</code>.</p>\n<p>You can use modifiers on parameters: <code>*</code> (zero or more), <code>+</code> (one or more), <code>?</code> (zero or one). For example, <code>/blog/:slug*</code> matches <code>/blog</code>, <code>/blog/a</code>, and <code>/blog/a/b/c</code>.</p>\n<p>Read more details on <a href=\"https://github.com/pillarjs/path-to-regexp\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">path-to-regexp<span class=\"inline-flex not-prose\"></span></a> documentation.</p>\n<h3 id=\"wildcard-path-matching\" data-docs-heading=\"\">Wildcard Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#wildcard-path-matching\"><span></span></a></h3>\n<p>To match a wildcard path you can use <code>*</code> after a parameter, for example <code>/blog/:slug*</code> will match <code>/blog/a/b/c/d/hello-world</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the value</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-slug-:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the key</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my other custom header value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"regex-path-matching\" data-docs-heading=\"\">Regex Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#regex-path-matching\"><span></span></a></h3>\n<p>To match a regex path you can wrap the regex in parenthesis after a parameter, for example <code>/blog/:slug(\\\\d{1,})</code> will match <code>/blog/123</code> but not <code>/blog/abc</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:post(\\\\d{1,})'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The following characters <code>(</code>, <code>)</code>, <code>{</code>, <code>}</code>, <code>:</code>, <code>*</code>, <code>+</code>, <code>?</code> are used for regex path matching, so when used in the <code>source</code> as non-special values they must be escaped by adding <code>\\\\</code> before them:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // this will match `/english(default)/something` being requested</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/english\\\\(default\\\\)/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'value'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"header-cookie-and-query-matching\" data-docs-heading=\"\">Header, Cookie, and Query Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#header-cookie-and-query-matching\"><span></span></a></h2>\n<p>To only apply a header when header, cookie, or query values also match the <code>has</code> field or don't match the <code>missing</code> field can be used. Both the <code>source</code> and all <code>has</code> items must match and all <code>missing</code> items must not match for the header to be applied.</p>\n<p><code>has</code> and <code>missing</code> items can have the following fields:</p>\n<ul>\n<li><code>type</code>: <code>String</code> - must be either <code>header</code>, <code>cookie</code>, <code>host</code>, or <code>query</code>.</li>\n<li><code>key</code>: <code>String</code> - the key from the selected type to match against.</li>\n<li><code>value</code>: <code>String</code> or <code>undefined</code> - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value <code>first-(?&lt;paramName&gt;.*)</code> is used for <code>first-second</code> then <code>second</code> will be usable in the destination with <code>:paramName</code>.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-add-header` is present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // the `x-another-header` header will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-add-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-another-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-no-header` is not present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // the `x-another-header` header will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        missing</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-no-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-another-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the source, query, and cookie are matched,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // the `x-authorized` header will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/specific/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'query'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // the page value will not be available in the</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // header key/values since value is provided and</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // doesn't use a named capture group e.g. (?&lt;page&gt;home)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'home'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'cookie'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'true'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-authorized` is present and</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // contains a matching value, the `x-another-header` will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '(?&lt;authorized&gt;yes|true)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-another-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the host is `example.com`,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this header will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'host'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-another-header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> ':authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"headers-with-basepath-support\" data-docs-heading=\"\">Headers with basePath support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#headers-with-basepath-support\"><span></span></a></h2>\n<p>When leveraging <a href=\"/docs/app/api-reference/config/next-config-js/basePath\"><code>basePath</code> support</a> with headers each <code>source</code> is automatically prefixed with the <code>basePath</code> unless you add <code>basePath: false</code> to the header:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/docs'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/with-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // becomes /docs/with-basePath</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/without-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // is not modified since basePath: false is set</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"headers-with-i18n-support\" data-docs-heading=\"\">Headers with i18n support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#headers-with-i18n-support\"><span></span></a></h2>\n<p>When leveraging <a href=\"/docs/app/guides/internationalization\"><code>i18n</code> support</a> with headers each <code>source</code> is automatically prefixed to handle the configured <code>locales</code> unless you add <code>locale: false</code> to the header. If <code>locale: false</code> is used you must prefix the <code>source</code> with a locale for it to be matched correctly.</p>\n<!-- -->\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  i18n</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    locales</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'en'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'fr'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'de'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    defaultLocale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'en'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/with-locale'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // automatically handles all locales</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // does not handle locales automatically since locale: false is set</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/nl/with-locale-manual'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        locale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // this matches '/' since `en` is the defaultLocale</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        locale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // `/` or `/fr` routes like /:path* would</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/(.*)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-hello'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'world'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"cache-control\" data-docs-heading=\"\">Cache-Control<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cache-control\"><span></span></a></h2>\n<p>Next.js sets the <code>Cache-Control</code> header of <code>public, max-age=31536000, immutable</code> for truly immutable assets. It cannot be overridden. These immutable files contain a SHA-hash in the file name, so they can be safely cached indefinitely. For example, <a href=\"/docs/app/getting-started/images#local-images\">Static Image Imports</a>. You cannot set <code>Cache-Control</code> headers in <code>next.config.js</code> for these assets.</p>\n<p>However, you can set <code>Cache-Control</code> headers for other responses or data.</p>\n<p>Learn more about <a href=\"/docs/app/getting-started/caching\">caching</a> with the App Router.</p>\n<!-- -->\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<h3 id=\"cors\" data-docs-heading=\"\">CORS<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cors\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/CORS\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Cross-Origin Resource Sharing (CORS)<span class=\"inline-flex not-prose\"></span></a> is a security feature that allows you to control which sites can access your resources. You can set the <code>Access-Control-Allow-Origin</code> header to allow a specific origin to access your <!-- -->Route Handlers<!-- -->.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">headers</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"/api/:path*\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        headers</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"Access-Control-Allow-Origin\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"*\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Set your origin</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"Access-Control-Allow-Methods\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"GET, POST, PUT, DELETE, OPTIONS\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"Access-Control-Allow-Headers\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"Content-Type, Authorization\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ];</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span></code></pre></div>\n<h3 id=\"x-dns-prefetch-control\" data-docs-heading=\"\">X-DNS-Prefetch-Control<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#x-dns-prefetch-control\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the <a href=\"https://developer.mozilla.org/docs/Glossary/DNS\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">DNS<span class=\"inline-flex not-prose\"></span></a> is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'X-DNS-Prefetch-Control'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'on'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"strict-transport-security\" data-docs-heading=\"\">Strict-Transport-Security<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#strict-transport-security\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a <code>max-age</code> of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Strict-Transport-Security'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'max-age=63072000; includeSubDomains; preload'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"x-frame-options\" data-docs-heading=\"\">X-Frame-Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#x-frame-options\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> indicates whether the site should be allowed to be displayed within an <code>iframe</code>. This can prevent against clickjacking attacks.</p>\n<p><strong>This header has been superseded by CSP's <code>frame-ancestors</code> option</strong>, which has better support in modern browsers (see <a href=\"/docs/app/guides/content-security-policy\">Content Security Policy</a> for configuration details).</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'X-Frame-Options'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'SAMEORIGIN'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"permissions-policy\" data-docs-heading=\"\">Permissions-Policy<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#permissions-policy\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/Permissions-Policy\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> allows you to control which features and APIs can be used in the browser. It was previously named <code>Feature-Policy</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Permissions-Policy'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'camera=(), microphone=(), geolocation=(), browsing-topics=()'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"x-content-type-options\" data-docs-heading=\"\">X-Content-Type-Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#x-content-type-options\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> prevents the browser from attempting to guess the type of content if the <code>Content-Type</code> header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files.</p>\n<p>For example, a user trying to download an image, but having it treated as a different <code>Content-Type</code> like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is <code>nosniff</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'X-Content-Type-Options'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nosniff'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"referrer-policy\" data-docs-heading=\"\">Referrer-Policy<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#referrer-policy\"><span></span></a></h3>\n<p><a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">This header<span class=\"inline-flex not-prose\"></span></a> controls how much information the browser includes when navigating from the current website (origin) to another.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  key</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Referrer-Policy'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  value</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'origin-when-cross-origin'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"content-security-policy\" data-docs-heading=\"\">Content-Security-Policy<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#content-security-policy\"><span></span></a></h3>\n<p>Learn more about adding a <a href=\"/docs/app/guides/content-security-policy\">Content Security Policy</a> to your application.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.3.0</code></td><td><code>missing</code> added.</td></tr><tr><td><code>v10.2.0</code></td><td><code>has</code> added.</td></tr><tr><td><code>v9.5.0</code></td><td>Headers added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/htmlLimitedBots",
    "title": "next.config.js: htmlLimitedBots | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">htmlLimitedBots</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 3, 2025</div><p>The <code>htmlLimitedBots</code> config allows you to specify a list of user agents that should receive blocking metadata instead of <a href=\"/docs/app/api-reference/functions/generate-metadata#streaming-metadata\">streaming metadata</a>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  htmlLimitedBots</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /MySpecialBot</span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-string-expression)\">MyAnotherSpecialBot</span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-string-expression)\">SimpleCrawler/</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> config</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"default-list\" data-docs-heading=\"\">Default list<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#default-list\"><span></span></a></h2>\n<p>Next.js includes a default list of HTML limited bots, including:</p>\n<ul>\n<li>Google crawlers (e.g. Mediapartners-Google, AdsBot-Google, Google-PageRenderer)</li>\n<li>Bingbot</li>\n<li>Twitterbot</li>\n<li>Slackbot</li>\n</ul>\n<p>See the full list <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/html-bots.ts\" rel=\"noopener noreferrer\" target=\"_blank\">here<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>Specifying a <code>htmlLimitedBots</code> config will override the Next.js' default list. However, this is advanced behavior, and the default should be sufficient for most cases.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  htmlLimitedBots</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /MySpecialBot</span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-string-expression)\">MyAnotherSpecialBot</span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-string-expression)\">SimpleCrawler/</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> config</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"disabling\" data-docs-heading=\"\">Disabling<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disabling\"><span></span></a></h2>\n<p>To fully disable streaming metadata:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  htmlLimitedBots</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /.</span><span style=\"color:var(--shiki-token-keyword)\">*</span><span style=\"color:var(--shiki-token-string-expression)\">/</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> config</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td>15.2.0</td><td><code>htmlLimitedBots</code> option introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/httpAgentOptions",
    "title": "next.config.js: httpAgentOptions | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">httpAgentOptions</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>In Node.js versions prior to 18, Next.js automatically polyfills <code>fetch()</code> with <a href=\"/docs/architecture/supported-browsers#polyfills\">undici</a> and enables <a href=\"https://developer.mozilla.org/docs/Web/HTTP/Headers/Keep-Alive\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">HTTP Keep-Alive<span class=\"inline-flex not-prose\"></span></a> by default.</p>\n<p>To disable HTTP Keep-Alive for all <code>fetch()</code> calls on the server-side, open <code>next.config.js</code> and add the <code>httpAgentOptions</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  httpAgentOptions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    keepAlive</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/images",
    "title": "next.config.js: images | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">images</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>If you want to use a cloud provider to optimize images instead of using the Next.js built-in Image Optimization API, you can configure <code>next.config.js</code> with the following:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    loader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'custom'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    loaderFile</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> './my/image/loader.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This <code>loaderFile</code> must point to a file relative to the root of your Next.js application. The file must export a default function that returns a string, for example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">my/image/loader.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> myImageLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?w=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">&amp;q=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Alternatively, you can use the <a href=\"/docs/app/api-reference/components/image#loader\"><code>loader</code> prop</a> to pass the function to each instance of <code>next/image</code>.</p><blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Customizing the image loader file, which accepts a function, requires using <a href=\"/docs/app/getting-started/server-and-client-components\">Client Components</a> to serialize the provided function.</p>\n</blockquote><p>To learn more about configuring the behavior of the built-in <a href=\"/docs/app/api-reference/components/image\">Image Optimization API</a> and the <a href=\"/docs/app/api-reference/components/image\">Image Component</a>, see <a href=\"/docs/app/api-reference/components/image#configuration-options\">Image Configuration Options</a> for available options.</p>\n<!-- -->\n<h2 id=\"example-loader-configuration\" data-docs-heading=\"\">Example Loader Configuration<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#example-loader-configuration\"><span></span></a></h2>\n<ul>\n<li><a href=\"#akamai\">Akamai</a></li>\n<li><a href=\"#aws-cloudfront\">AWS CloudFront</a></li>\n<li><a href=\"#cloudinary\">Cloudinary</a></li>\n<li><a href=\"#cloudflare\">Cloudflare</a></li>\n<li><a href=\"#contentful\">Contentful</a></li>\n<li><a href=\"#fastly\">Fastly</a></li>\n<li><a href=\"#gumlet\">Gumlet</a></li>\n<li><a href=\"#imageengine\">ImageEngine</a></li>\n<li><a href=\"#imgix\">Imgix</a></li>\n<li><a href=\"#pixelbin\">PixelBin</a></li>\n<li><a href=\"#sanity\">Sanity</a></li>\n<li><a href=\"#sirv\">Sirv</a></li>\n<li><a href=\"#supabase\">Supabase</a></li>\n<li><a href=\"#thumbor\">Thumbor</a></li>\n<li><a href=\"#imagekitio\">Imagekit</a></li>\n<li><a href=\"#nitrogen-aio\">Nitrogen AIO</a></li>\n</ul>\n<h3 id=\"akamai\" data-docs-heading=\"\">Akamai<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#akamai\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://techdocs.akamai.com/ivm/reference/test-images-on-demand</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> akamaiLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?imwidth=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"aws-cloudfront\" data-docs-heading=\"\">AWS CloudFront<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#aws-cloudfront\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://aws.amazon.com/developer/application-security-performance/articles/image-optimization</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> cloudfrontLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'format'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'width'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'quality'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"cloudinary\" data-docs-heading=\"\">Cloudinary<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cloudinary\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Demo: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/turtles.jpg</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> cloudinaryLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'f_auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'c_limit'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `w_</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `q_</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">params</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">','</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">}${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"cloudflare\" data-docs-heading=\"\">Cloudflare<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cloudflare\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://developers.cloudflare.com/images/transform-images</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> cloudflareLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">`width=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `quality=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'format=auto'</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com/cdn-cgi/image/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">params</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">','</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"contentful\" data-docs-heading=\"\">Contentful<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#contentful\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://www.contentful.com/developers/docs/references/images-api/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> contentfulLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'fm'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'webp'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'q'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"fastly\" data-docs-heading=\"\">Fastly<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#fastly\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://developer.fastly.com/reference/io/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> fastlyLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'webp'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'width'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'quality'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"gumlet\" data-docs-heading=\"\">Gumlet<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#gumlet\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://docs.gumlet.com/reference/image-transform-size</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> gumletLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'format'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'q'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"imageengine\" data-docs-heading=\"\">ImageEngine<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#imageengine\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://support.imageengine.io/hc/en-us/articles/360058880672-Directives</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> imageengineLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> compression</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> 100</span><span style=\"color:var(--shiki-token-keyword)\"> -</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 50</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">`w_</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `cmpr_</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">compression</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?imgeng=/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">params</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">}</span></span></code></pre></div>\n<h3 id=\"imgix\" data-docs-heading=\"\">Imgix<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#imgix\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Demo: https://static.imgix.net/daisy.png?format=auto&amp;fit=max&amp;w=300</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> imgixLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.searchParams</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.getAll</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'auto'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">','</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> 'format'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'fit'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'fit'</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> 'max'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'q'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 50</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"pixelbin\" data-docs-heading=\"\">PixelBin<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#pixelbin\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Doc (Resize): https://www.pixelbin.io/docs/transformations/basic/resize/#width-w</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Doc (Optimise): https://www.pixelbin.io/docs/optimizations/quality/#image-quality-when-delivering</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Doc (Auto Format Delivery): https://www.pixelbin.io/docs/optimizations/format/#automatic-format-selection-with-f_auto-url-parameter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> pixelBinLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> name</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> '&lt;your-cloud-name&gt;'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> opt</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> `t.resize(w:</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">)~t.compress(q:</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">)`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://cdn.pixelbin.io/v2/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">name</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">opt</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?f_auto=true`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"sanity\" data-docs-heading=\"\">Sanity<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#sanity\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://www.sanity.io/docs/image-urls</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> sanityLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> prj</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> 'zp7mbokg'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> dataset</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> 'production'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://cdn.sanity.io/images/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">prj</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">dataset</span><span style=\"color:var(--shiki-token-keyword)\">}${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'format'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'fit'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'max'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  if</span><span style=\"color:var(--shiki-color-text)\"> (quality) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'q'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> quality</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"sirv\" data-docs-heading=\"\">Sirv<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#sirv\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://sirv.com/help/articles/dynamic-imaging/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> sirvLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.searchParams</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'format'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.getAll</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'format'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">','</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> 'optimal'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'w'</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'q'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 85</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"supabase\" data-docs-heading=\"\">Supabase<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#supabase\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://supabase.com/docs/guides/storage/image-transformations#nextjs-loader</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> supabaseLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'width'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> width</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  url</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">searchParams</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'quality'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> (quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"thumbor\" data-docs-heading=\"\">Thumbor<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#thumbor\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://thumbor.readthedocs.io/en/latest/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> thumborLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">x0`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `filters:quality(</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 75</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">)`</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://example.com</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">params</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">}${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"imagekitio\" data-docs-heading=\"\">ImageKit.io<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#imagekitio\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://imagekit.io/docs/image-transformation</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> imageKitLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">`w-</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> `q-</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">quality </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-constant)\"> 80</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://ik.imagekit.io/your_imagekit_id/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">src</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">?tr=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">params</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">','</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"nitrogen-aio\" data-docs-heading=\"\">Nitrogen AIO<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#nitrogen-aio\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Docs: https://docs.n7.io/aio/intergrations/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> aioLoader</span><span style=\"color:var(--shiki-color-text)\">({ src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> width</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> quality }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(src</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> window</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">location</span><span style=\"color:var(--shiki-color-text)\">.href)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.searchParams</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> aioParams</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> params</span><span style=\"color:var(--shiki-token-function)\">.getAll</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'aio'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  aioParams</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`w-</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">width</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  if</span><span style=\"color:var(--shiki-color-text)\"> (quality) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    aioParams</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`q-</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">quality</span><span style=\"color:var(--shiki-token-function)\">.toString</span><span style=\"color:var(--shiki-color-text)\">()</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  params</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'aio'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> aioParams</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">';'</span><span style=\"color:var(--shiki-color-text)\">))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-color-text)\">.href</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath",
    "title": "next.config.js: cacheHandler | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Custom Next.js Cache Handler</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->January 8, 2026</div><p>You can configure the Next.js cache location if you want to persist cached pages and data to durable storage, or share the cache across multiple containers or instances of your Next.js application.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: The <code>cacheHandler</code> (singular) configuration is specifically used by Next.js for server cache operations such as storing and revalidating ISR, route handler responses, and optimized images. It is <strong>not</strong> used by <code>'use cache'</code> directives. For <code>'use cache'</code> directives, use <a href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><code>cacheHandlers</code></a> (plural) instead.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./cache-handler.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheMaxMemorySize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 0</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // disable default in-memory caching</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>View an example of a <a href=\"/docs/app/guides/self-hosting#configuring-caching\">custom cache handler</a> and learn more about the implementation.</p>\n<h2 id=\"api-reference\" data-docs-heading=\"\">API Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#api-reference\"><span></span></a></h2>\n<p>The cache handler can implement the following methods: <code>get</code>, <code>set</code>, <code>revalidateTag</code>, and <code>resetRequestCache</code>.</p>\n<h3 id=\"get\" data-docs-heading=\"\"><code>get()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#get\"><span></span></a></h3>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>key</code></td><td><code>string</code></td><td>The key to the cached value.</td></tr><tr><td><code>ctx</code></td><td><code>object</code></td><td>Context including the cache entry kind.</td></tr></tbody></table></div>\n<p>The <code>ctx</code> parameter contains a <code>kind</code> property that indicates the type of cache entry being retrieved. Possible values include <code>'APP_PAGE'</code>, <code>'APP_ROUTE'</code>, <code>'PAGES'</code>, <code>'FETCH'</code>, and <code>'IMAGE'</code>.</p>\n<p>Returns the cached value or <code>null</code> if not found.</p>\n<h3 id=\"set\" data-docs-heading=\"\"><code>set()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#set\"><span></span></a></h3>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>key</code></td><td><code>string</code></td><td>The key to store the data under.</td></tr><tr><td><code>data</code></td><td>Data or <code>null</code></td><td>The data to be cached.</td></tr><tr><td><code>ctx</code></td><td><code>{ tags: [] }</code></td><td>The cache tags provided.</td></tr></tbody></table></div>\n<p>The <code>data</code> object contains a <code>kind</code> property that indicates the type of cache entry. For image optimization, <code>kind</code> will be <code>'IMAGE'</code> and the data will include properties like <code>buffer</code>, <code>etag</code>, <code>extension</code>, and <code>revalidate</code>.</p>\n<p>Returns <code>Promise&lt;void&gt;</code>.</p>\n<h3 id=\"revalidatetag\" data-docs-heading=\"\"><code>revalidateTag()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#revalidatetag\"><span></span></a></h3>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Parameter</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>tag</code></td><td><code>string</code> or <code>string[]</code></td><td>The cache tags to revalidate.</td></tr></tbody></table></div>\n<p>Returns <code>Promise&lt;void&gt;</code>. Learn more about <a href=\"/docs/app/guides/incremental-static-regeneration\">revalidating data</a> or the <a href=\"/docs/app/api-reference/functions/revalidateTag\"><code>revalidateTag()</code></a> function.</p>\n<h3 id=\"resetrequestcache\" data-docs-heading=\"\"><code>resetRequestCache()</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#resetrequestcache\"><span></span></a></h3>\n<p>This method resets the temporary in-memory cache for a single request before the next request.</p>\n<p>Returns <code>void</code>.</p>\n<p><strong>Good to know:</strong></p>\n<ul>\n<li><code>revalidatePath</code> is a convenience layer on top of cache tags. Calling <code>revalidatePath</code> will call your <code>revalidateTag</code> function, which you can then choose if you want to tag cache keys based on the path.</li>\n</ul>\n<h2 id=\"image-optimization-caching\" data-docs-heading=\"\">Image Optimization Caching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#image-optimization-caching\"><span></span></a></h2>\n<p>The <code>cacheHandler</code> can also be used for caching optimized images from <code>next/image</code>. To enable this, set <code>images.customCacheHandler</code> to <code>true</code> in your <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheHandler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./cache-handler.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  images</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    customCacheHandler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This opt-in flag will become the default behavior in the next major version. Setting it now allows you to prepare your cache handler for image optimization entries.</p>\n</blockquote>\n<p>You can use the <code>kind</code> property to differentiate between cache entry types and handle images separately if needed, for example to implement an eviction policy or store images in a different location.</p>\n<p>When handling image cache entries, the <code>kind</code> will be <code>'IMAGE'</code> and the data will include <code>buffer</code>, <code>etag</code>, <code>extension</code>, and <code>revalidate</code> properties.</p>\n<h2 id=\"platform-support\" data-docs-heading=\"\">Platform Support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#platform-support\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Deployment Option</th><th class=\"min-w-[12ch]\">Supported</th></tr></thead><tbody><tr><td><a href=\"/docs/app/getting-started/deploying#nodejs-server\">Node.js server</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#docker\">Docker container</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#static-export\">Static export</a></td><td>No</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#adapters\">Adapters</a></td><td>Platform-specific</td></tr></tbody></table></div>\n<p>Learn how to <a href=\"/docs/app/guides/self-hosting#caching-and-isr\">configure ISR</a> when self-hosting Next.js.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.2.0</code></td><td><code>cacheHandler</code> support for image optimization caching.</td></tr><tr><td><code>v14.1.0</code></td><td>Renamed to <code>cacheHandler</code> and became stable.</td></tr><tr><td><code>v13.4.0</code></td><td><code>incrementalCacheHandlerPath</code> support for <code>revalidateTag</code>.</td></tr><tr><td><code>v13.4.0</code></td><td><code>incrementalCacheHandlerPath</code> support for standalone output.</td></tr><tr><td><code>v12.2.0</code></td><td>Experimental <code>incrementalCacheHandlerPath</code> added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/inlineCss",
    "title": "next.config.js: inlineCss | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">inlineCss<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 3, 2026</div><h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>Experimental support for inlining CSS in the <code>&lt;head&gt;</code>. When this flag is enabled, all places where we normally generate a <code>&lt;link&gt;</code> tag will instead have a generated <code>&lt;style&gt;</code> tag.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    inlineCss</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"trade-offs\" data-docs-heading=\"\">Trade-Offs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#trade-offs\"><span></span></a></h2>\n<ul>\n<li><strong>Enable</strong> if you use atomic CSS (like Tailwind) and want to optimize first-load performance for new visitors</li>\n<li><strong>Skip</strong> if returning visitors are common and you want them to benefit from cached stylesheets</li>\n</ul>\n<h3 id=\"when-inline-css-helps\" data-docs-heading=\"\">When Inline CSS Helps<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#when-inline-css-helps\"><span></span></a></h3>\n<p>Normally, the browser must download HTML, parse it, discover CSS <code>&lt;link&gt;</code> tags, then request stylesheets before it can render. Inlining <a href=\"https://web.dev/learn/performance/optimize-resource-loading#inline_critical_css\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">eliminates this request waterfall<span class=\"inline-flex not-prose\"></span></a>, so that styles arrive with the HTML, so the browser can render immediately.</p>\n<p>This benefit is strongest with:</p>\n<ul>\n<li>\n<p><strong>First-time visitors</strong>: Since CSS files are render-blocking, inlining eliminates the initial download delay that first-time visitors experience. Returning visitors with cached stylesheets won't see this benefit.</p>\n</li>\n<li>\n<p><strong>Performance metrics</strong>: By removing additional network requests for CSS files, inlining can significantly improve <a href=\"https://web.dev/articles/fcp\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">First Contentful Paint (FCP)<span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://web.dev/articles/lcp\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Largest Contentful Paint (LCP)<span class=\"inline-flex not-prose\"></span></a>.</p>\n</li>\n<li>\n<p><strong>Slow connections</strong>: For users on high-latency networks, each additional request adds delay. Inlining reduces round trips, which matters most when connections are slow.</p>\n</li>\n<li>\n<p><strong>Atomic CSS (Tailwind)</strong>: Utility-first frameworks generate only the classes you use, keeping CSS small. The styles for a page don't grow proportionally with page complexity—they're typically compact regardless of how much UI you build. This makes inlining practical since you get the performance benefit without significantly bloating HTML.</p>\n</li>\n</ul>\n<h3 id=\"when-external-css-is-better\" data-docs-heading=\"\">When External CSS is Better<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#when-external-css-is-better\"><span></span></a></h3>\n<p>Inlined styles cannot be cached separately from HTML. Every page load re-downloads the same CSS.</p>\n<p>This trade-off matters most with:</p>\n<ul>\n<li>\n<p><strong>Returning visitors</strong>: Users who visit your site repeatedly would benefit from cached external stylesheets. With inlining, they re-download styles on every visit.</p>\n</li>\n<li>\n<p><strong>Large CSS bundles</strong>: External stylesheets cache independently and load efficiently on modern infrastructure. Inlined CSS arrives with every HTML response, increasing <a href=\"https://web.dev/articles/ttfb\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Time to First Byte (TTFB)<span class=\"inline-flex not-prose\"></span></a> and preventing browsers from caching styles separately. This trade-off works for small CSS (atomic frameworks like Tailwind), but adds overhead for larger bundles (component libraries like Bootstrap or Material UI).</p>\n</li>\n<li>\n<p><strong>Many pages sharing styles</strong>: External stylesheets cached on one page speed up navigation to other pages. Inlined styles provide no cross-page caching benefit.</p>\n</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<p>This feature is currently experimental and has some known limitations:</p>\n<ul>\n<li>CSS inlining is applied globally and cannot be configured on a per-page basis</li>\n<li>Styles are duplicated during initial page load - once within <code>&lt;style&gt;</code> tags for SSR and once in the RSC payload</li>\n<li>When navigating to prerendered pages, styles will use <code>&lt;link&gt;</code> tags instead of inline CSS to avoid duplication</li>\n<li>This feature is not available in development mode and only works in production builds</li>\n</ul>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/instrumentationClientInject",
    "title": "next.config.js: instrumentationClientInject | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">instrumentationClientInject</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 20, 2026</div><p><code>instrumentationClientInject</code> is a list of modules that are imported on the client for their side effects before the user's <a href=\"/docs/app/api-reference/file-conventions/instrumentation-client\"><code>instrumentation-client.{js,ts}</code></a> file runs, ahead of React hydration.</p>\n<p>This option is primarily intended for <strong><code>next.config.js</code> plugins</strong> (for example, wrappers like <code>withSentry</code> or <code>withAnalytics</code> that extend a project's config). It lets such a plugin inject its own client instrumentation module — including a navigation hook — without requiring every project to author or modify an <code>instrumentation-client</code> file. Application code should generally continue to use the <a href=\"/docs/app/api-reference/file-conventions/instrumentation-client\"><code>instrumentation-client.{js,ts}</code></a> file convention directly.</p>\n<p>A plugin typically appends its own module to whatever the project already has configured:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">withMyInstrumentation.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> withMyInstrumentation</span><span style=\"color:var(--shiki-color-text)\">(nextConfig </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\"> {}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    ...</span><span style=\"color:var(--shiki-color-text)\">nextConfig</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    instrumentationClientInject</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">      ...</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">nextConfig</span><span style=\"color:var(--shiki-color-text)\">.instrumentationClientInject </span><span style=\"color:var(--shiki-token-keyword)\">??</span><span style=\"color:var(--shiki-color-text)\"> [])</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      'my-instrumentation-package/client'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>It can also be set directly:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  instrumentationClientInject</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'my-analytics-package'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    './lib/sentry-client.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Each entry is one of:</p>\n<ul>\n<li>A bare npm package name, resolved from the project's <code>node_modules</code>.</li>\n<li>A path relative to the project root.</li>\n</ul>\n<h2 id=\"execution-order\" data-docs-heading=\"\">Execution order<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#execution-order\"><span></span></a></h2>\n<p>Modules run on the client in this order:</p>\n<ol>\n<li>Each entry in <code>instrumentationClientInject</code>, in array order.</li>\n<li>The project's <code>instrumentation-client.{js,ts}</code> file, if present.</li>\n<li>React hydration.</li>\n</ol>\n<h2 id=\"router-navigation-hook\" data-docs-heading=\"\">Router navigation hook<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#router-navigation-hook\"><span></span></a></h2>\n<p>Each injected module may optionally export an <code>onRouterTransitionStart</code> function with the same signature as the one documented for the <a href=\"/docs/app/api-reference/file-conventions/instrumentation-client#router-navigation-tracking\"><code>instrumentation-client</code> file convention</a>. Next.js composes a single hook that fans out to every exported <code>onRouterTransitionStart</code> on each navigation, calling them in array order, with the user file's hook running last.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">lib/sentry-client.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Side-effectful setup runs at load time.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">setupSentry</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> onRouterTransitionStart</span><span style=\"color:var(--shiki-color-text)\">(url</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> navigationType) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  recordNavigationBreadcrumb</span><span style=\"color:var(--shiki-color-text)\">(url</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> navigationType)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Modules that do not export <code>onRouterTransitionStart</code> are skipped during navigation.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version history<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td><code>instrumentationClientInject</code> introduced</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/logging",
    "title": "next.config.js: logging | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">logging</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->February 12, 2026</div>\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<h3 id=\"fetching\" data-docs-heading=\"\">Fetching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#fetching\"><span></span></a></h3><p>You can configure the logging level and whether the full URL is logged to the console when running Next.js in development mode.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    fetches</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      fullUrl</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Any <code>fetch</code> requests that are restored from the <a href=\"/docs/app/api-reference/config/next-config-js/serverComponentsHmrCache\">Server Components HMR cache</a> are not logged by default. However, this can be enabled by setting <code>logging.fetches.hmrRefreshes</code> to <code>true</code>.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    fetches</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      hmrRefreshes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><h3 id=\"server-functions\" data-docs-heading=\"\">Server Functions<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#server-functions\"><span></span></a></h3><p><a href=\"https://react.dev/reference/rsc/server-functions\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Server Function<span class=\"inline-flex not-prose\"></span></a> invocations are logged by default during development. You can disable this by setting <code>logging.serverFunctions</code> to <code>false</code>.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    serverFunctions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>When enabled, the terminal displays each Server Function call with its function name, arguments, and duration:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">POST</span><span style=\"color:var(--shiki-token-string)\"> /</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  └─</span><span style=\"color:var(--shiki-token-string)\"> ƒ</span><span style=\"color:var(--shiki-token-string)\"> myAction</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-function)\">arg1,</span><span style=\"color:var(--shiki-token-string)\"> arg2</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-string)\">in</span><span style=\"color:var(--shiki-token-string)\"> 5ms</span><span style=\"color:var(--shiki-token-string)\"> app/actions.ts</span></span></code></pre></div>\n<h3 id=\"incoming-requests\" data-docs-heading=\"\">Incoming Requests<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#incoming-requests\"><span></span></a></h3>\n<p>By default all the incoming requests will be logged in the console during development. You can use the <code>incomingRequests</code> option to decide which requests to ignore.\nSince this is only logged in development, this option doesn't affect production builds.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    incomingRequests</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ignore</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">/\\api\\/v1\\/health/</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Or you can disable incoming request logging by setting <code>incomingRequests</code> to <code>false</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    incomingRequests</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"browser-console-logs\" data-docs-heading=\"\">Browser Console Logs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#browser-console-logs\"><span></span></a></h3>\n<p>You can forward browser console logs (such as <code>console.log</code>, <code>console.warn</code>, <code>console.error</code>) to the terminal during development. This is useful for debugging client-side code without needing to check the browser's developer tools.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    browserToTerminal</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"options-1\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options-1\"><span></span></a></h4>\n<p>The <code>browserToTerminal</code> option accepts the following values:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Value</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>'warn'</code></td><td>Forward only warnings and errors, by default</td></tr><tr><td><code>'error'</code></td><td>Forward only errors</td></tr><tr><td><code>true</code></td><td>Forward all console output (log, info, warn, error)</td></tr><tr><td><code>false</code></td><td>Disable browser log forwarding</td></tr></tbody></table></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    browserToTerminal</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'warn'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"source-location\" data-docs-heading=\"\">Source Location<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#source-location\"><span></span></a></h4>\n<p>When enabled, browser logs include source location information (file path and line number) by default. For example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Home</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      type</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"button\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Hello World'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      Click me</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>Clicking the button prints this message to the terminal:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">[browser] Hello World (</span><span style=\"color:var(--shiki-token-function)\">app/page.tsx:8:17</span><span style=\"color:var(--shiki-color-text)\">)</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"disabling-logging\" data-docs-heading=\"\">Disabling Logging<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disabling-logging\"><span></span></a></h3>\n<p>In addition, you can disable the development logging by setting <code>logging</code> to <code>false</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  logging</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.2.0</code></td><td><code>browserToTerminal</code> added (moved from <code>experimental.browserDebugInfoInTerminal</code>)</td></tr><tr><td><code>v15.4.0</code></td><td><code>experimental.browserDebugInfoInTerminal</code> introduced</td></tr><tr><td><code>v15.2.0</code></td><td><code>incomingRequests</code> added</td></tr><tr><td><code>v15.0.0</code></td><td><code>logging: false</code> option added, <code>fetches.hmrRefreshes</code> added for App Router</td></tr><tr><td><code>v14.0.0</code></td><td><code>logging.fetches</code> moved to stable for App Router</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/mdxRs",
    "title": "next.config.js: mdxRs | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">mdxRs<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->November 5, 2025</div><p>For experimental use with <code>@next/mdx</code>. Compiles MDX files using the new Rust compiler.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> withMDX</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'@next/mdx'</span><span style=\"color:var(--shiki-color-text)\">)()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pageExtensions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'mdx'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    mdxRs</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> withMDX</span><span style=\"color:var(--shiki-color-text)\">(nextConfig)</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/onDemandEntries",
    "title": "next.config.js: onDemandEntries | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">onDemandEntries</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Next.js exposes some options that give you some control over how the server will dispose or keep in memory built pages in development.</p>\n<p>To change the defaults, open <code>next.config.js</code> and add the <code>onDemandEntries</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  onDemandEntries</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // period (in ms) where the server will keep pages in the buffer</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    maxInactiveAge</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 25</span><span style=\"color:var(--shiki-token-keyword)\"> *</span><span style=\"color:var(--shiki-token-constant)\"> 1000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // number of pages that should be kept simultaneously without being disposed</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    pagesBufferLength</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 2</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/optimizePackageImports",
    "title": "next.config.js: optimizePackageImports | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">optimizePackageImports<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->December 19, 2025</div>\n<p>Some packages can export hundreds or thousands of modules, which can cause performance issues in development and production.</p>\n<p>Adding a package to <code>experimental.optimizePackageImports</code> will only load the modules you are actually using, while still giving you the convenience of writing import statements with many named exports.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    optimizePackageImports</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'package-name'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The following libraries are optimized by default:</p>\n<ul>\n<li><code>lucide-react</code></li>\n<li><code>date-fns</code></li>\n<li><code>lodash-es</code></li>\n<li><code>ramda</code></li>\n<li><code>antd</code></li>\n<li><code>react-bootstrap</code></li>\n<li><code>ahooks</code></li>\n<li><code>@ant-design/icons</code></li>\n<li><code>@headlessui/react</code></li>\n<li><code>@headlessui-float/react</code></li>\n<li><code>@heroicons/react/20/solid</code></li>\n<li><code>@heroicons/react/24/solid</code></li>\n<li><code>@heroicons/react/24/outline</code></li>\n<li><code>@visx/visx</code></li>\n<li><code>@tremor/react</code></li>\n<li><code>rxjs</code></li>\n<li><code>@mui/material</code></li>\n<li><code>@mui/icons-material</code></li>\n<li><code>recharts</code></li>\n<li><code>react-use</code></li>\n<li><code>@material-ui/core</code></li>\n<li><code>@material-ui/icons</code></li>\n<li><code>@tabler/icons-react</code></li>\n<li><code>mui-core</code></li>\n<li><code>react-icons/*</code></li>\n<li><code>effect</code></li>\n<li><code>@effect/*</code></li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/output",
    "title": "next.config.js: output | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">output</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 8, 2025</div>\n<p>During a build, Next.js will automatically trace each page and its dependencies to determine all of the files that are needed for deploying a production version of your application.</p>\n<p>This feature helps reduce the size of deployments drastically. Previously, when deploying with Docker you would need to have all files from your package's <code>dependencies</code> installed to run <code>next start</code>. Starting with Next.js 12, you can leverage Output File Tracing in the <code>.next/</code> directory to only include the necessary files.</p>\n<p>Furthermore, this removes the need for the deprecated <code>serverless</code> target which can cause various issues and also creates unnecessary duplication.</p>\n<h2 id=\"how-it-works\" data-docs-heading=\"\">How it Works<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-it-works\"><span></span></a></h2>\n<p>During <code>next build</code>, Next.js will use <a href=\"https://github.com/vercel/nft\" rel=\"noopener noreferrer\" target=\"_blank\"><code>@vercel/nft</code><span class=\"inline-flex not-prose\"></span></a> to statically analyze <code>import</code>, <code>require</code>, and <code>fs</code> usage to determine all files that a page might load.</p>\n<p>Next.js' production server is also traced for its needed files and output at <code>.next/next-server.js.nft.json</code> which can be leveraged in production.</p>\n<p>To leverage the <code>.nft.json</code> files emitted to the <code>.next</code> output directory, you can read the list of files in each trace that are relative to the <code>.nft.json</code> file and then copy them to your deployment location.</p>\n<h2 id=\"automatically-copying-traced-files\" data-docs-heading=\"\">Automatically Copying Traced Files<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#automatically-copying-traced-files\"><span></span></a></h2>\n<p>Next.js can automatically create a <code>standalone</code> folder that copies only the necessary files for a production deployment including select files in <code>node_modules</code>.</p>\n<p>To leverage this automatic copying you can enable it in your <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  output</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'standalone'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This will create a folder at <code>.next/standalone</code> which can then be deployed on its own without installing <code>node_modules</code>.</p>\n<p>Additionally, a minimal <code>server.js</code> file is also output which can be used instead of <code>next start</code>. This minimal server does not copy the <code>public</code> or <code>.next/static</code> folders by default as these should ideally be handled by a CDN instead, although these folders can be copied to the <code>standalone/public</code> and <code>standalone/.next/static</code> folders manually, after which <code>server.js</code> file will serve these automatically.</p>\n<p>To copy these manually, you can use the <code>cp</code> command-line tool after you <code>next build</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">cp</span><span style=\"color:var(--shiki-token-string)\"> -r</span><span style=\"color:var(--shiki-token-string)\"> public</span><span style=\"color:var(--shiki-token-string)\"> .next/standalone/</span><span style=\"color:var(--shiki-token-punctuation)\"> &amp;&amp;</span><span style=\"color:var(--shiki-token-function)\"> cp</span><span style=\"color:var(--shiki-token-string)\"> -r</span><span style=\"color:var(--shiki-token-string)\"> .next/static</span><span style=\"color:var(--shiki-token-string)\"> .next/standalone/.next/</span></span></code></pre></div>\n<p>To start your minimal <code>server.js</code> file locally, run the following command:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">node</span><span style=\"color:var(--shiki-token-string)\"> .next/standalone/server.js</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>If your project needs to listen to a specific port or hostname, you can define <code>PORT</code> or <code>HOSTNAME</code> environment variables before running <code>server.js</code>. For example, run <code>PORT=8080 HOSTNAME=0.0.0.0 node server.js</code> to start the server on <code>http://0.0.0.0:8080</code>.</li>\n</ul>\n</blockquote>\n<!-- -->\n<h2 id=\"caveats\" data-docs-heading=\"\">Caveats<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caveats\"><span></span></a></h2>\n<ul>\n<li>While tracing in monorepo setups, the project directory is used for tracing by default. For <code>next build packages/web-app</code>, <code>packages/web-app</code> would be the tracing root and any files outside of that folder will not be included. To include files outside of this folder you can set <code>outputFileTracingRoot</code> in your <code>next.config.js</code>.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">packages/web-app/next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'path'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // this includes files from the monorepo base two directories up</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingRoot</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(__dirname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '../../'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<ul>\n<li>There are some cases in which Next.js might fail to include required files, or might incorrectly include unused files. In those cases, you can leverage <code>outputFileTracingExcludes</code> and <code>outputFileTracingIncludes</code> respectively in <code>next.config.js</code>. Each option accepts an object whose keys are <strong>route globs</strong> (matched with <a href=\"https://www.npmjs.com/package/picomatch#basic-globbing\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">picomatch<span class=\"inline-flex not-prose\"></span></a> against the route path, e.g. <code>/api/hello</code>) and whose values are <strong>glob patterns resolved from the project root</strong> that specify files to include or exclude in the trace.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:\nIn a monorepo, <code>project root</code> refers to the Next.js project root (the folder containing next.config.js, e.g., packages/web-app), not necessarily the monorepo root.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingExcludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/api/hello'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'./un-necessary-folder/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingIncludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/api/another'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'./necessary-folder/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/api/login/\\\\[\\\\[\\\\.\\\\.\\\\.slug\\\\]\\\\]'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      './node_modules/aws-crt/dist/bin/**/*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Using a <code>src/</code> directory does not change how you write these options:</p>\n<ul>\n<li><strong>Keys</strong> still match the route path (<code>'/api/hello'</code>, <code>'/products/[id]'</code>, etc.).</li>\n<li><strong>Values</strong> can reference paths under <code>src/</code> since they are resolved relative to the project root.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingIncludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/products/*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'src/lib/payments/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'src/config/runtime/**/*.json'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingExcludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/api/*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'src/temp/**/*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'public/large-logs/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also target all routes using a global key like <code>'/*'</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingIncludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'src/i18n/locales/**/*.json'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>These options are applied to server traces and do not affect routes that do not produce a server trace file:</p>\n<ul>\n<li>Edge Runtime routes are not affected.</li>\n<li>Fully static pages are not affected.</li>\n</ul>\n<p>In monorepos or when you need to include files outside the app folder, combine <code>outputFileTracingRoot</code> with includes:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'path'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Trace from the monorepo root</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingRoot</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(__dirname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '../../'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingIncludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/route1'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'../shared/assets/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>Prefer forward slashes (<code>/</code>) in patterns for cross-platform compatibility.</li>\n<li>Keep patterns as narrow as possible to avoid oversized traces (avoid <code>**/*</code> at the repo root).</li>\n</ul>\n</blockquote>\n<p>Common include patterns for native/runtime assets:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputFileTracingIncludes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    '/*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'node_modules/sharp/**/*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'node_modules/aws-crt/dist/bin/**/*'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/outputHashSalt",
    "title": "next.config.js: outputHashSalt | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">outputHashSalt</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 20, 2026</div><p><code>outputHashSalt</code> is an option that incorporates a configurable salt string into every content-addressed output filename (chunks, assets). Changing this value forces all output hashes to change, which is useful for invalidating cached assets across deployments without modifying source files.</p>\n<p>To configure the output hash salt, set <code>outputHashSalt</code> in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  outputHashSalt</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'my-deployment-salt'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>This works with both Webpack and Turbopack bundlers.</p>\n<p>The <code>NEXT_HASH_SALT</code> environment variable can also be used for the same purpose. When both are set, the values are <strong>concatenated</strong> (<code>outputHashSalt + NEXT_HASH_SALT</code>) to form the effective salt. This lets you combine a per-project salt baked into the config with a per-deployment salt injected at build time via environment variable.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NEXT_HASH_SALT</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">my-deployment-salt</span><span style=\"color:var(--shiki-token-function)\"> next</span><span style=\"color:var(--shiki-token-string)\"> build</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>16.3.0</code></td><td><code>outputHashSalt</code> was added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/pageExtensions",
    "title": "next.config.js: pageExtensions | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">pageExtensions</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 17, 2025</div>\n<p>By default, Next.js accepts files with the following extensions: <code>.tsx</code>, <code>.ts</code>, <code>.jsx</code>, <code>.js</code>. This can be modified to allow other extensions like markdown (<code>.md</code>, <code>.mdx</code>).</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> withMDX</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'@next/mdx'</span><span style=\"color:var(--shiki-color-text)\">)()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  pageExtensions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'jsx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'md'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'mdx'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> withMDX</span><span style=\"color:var(--shiki-color-text)\">(nextConfig)</span></span></code></pre></div>\n</div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/partialPrefetching",
    "title": "next.config.js: partialPrefetching | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">partialPrefetching</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 10, 2026</div><p><code>partialPrefetching</code> enables Partial Prefetching at the app level. The framework prefetches the static parts of each route by default; set <code>prefetch={true}</code> on individual links to use <a href=\"/docs/app/guides/optimizing-prefetching\">per-link prefetching</a> and fetch more.</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheComponents</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-color-text)\">  partialPrefetching</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p><code>partialPrefetching</code> requires <a href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><code>cacheComponents</code></a>. Without it, <code>next dev</code> and <code>next build</code> throw at config validation.</p>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Value</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>true</code></td><td>Enables Partial Prefetching across the app.</td></tr><tr><td><code>false</code></td><td>Default. No change to prefetch behavior.</td></tr></tbody></table></div>\n<h2 id=\"how-prefetches-resolve\" data-docs-heading=\"\">How prefetches resolve<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-prefetches-resolve\"><span></span></a></h2>\n<p>Before Partial Prefetching, Next.js prefetched per visible link: a page with N links to N routes produced ~N route prefetches as those links entered the viewport.</p>\n<p>With <code>partialPrefetching: true</code>, Next.js prefetches one reusable <a href=\"/docs/app/glossary#app-shell\">App Shell</a> per route instead. The App Shell contains rendered output that does not depend on a link's URL. URL-specific content, including content that depends on <code>params</code> or <code>searchParams</code>, resolves after navigation by default. App Shells are cached on the client, so links to the same route reuse one prefetch.</p>\n<p>The pattern is similar to per-route code splitting in single-page apps: one artifact per route, shared by every link that points to it.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Routes that read <code>cookies()</code> or <code>headers()</code> produce an App Shell that includes session data. The framework auto-detects this and caches the shell per session on the client.</p>\n</blockquote>\n<p>A link can ask for more than the App Shell with <a href=\"/docs/app/api-reference/components/link#prefetch\"><code>&lt;Link prefetch={true}&gt;</code></a>. The prefetch also resolves URL data like <code>params</code>, <code>searchParams</code>, and the full URL, and the cached content behind it. See <a href=\"/docs/app/guides/optimizing-prefetching\">Optimizing prefetching</a>.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you use <code>&lt;Link prefetch={true}&gt;</code> to a route that hasn't opted into Partial Prefetching, a dev console error suggests enabling <code>partialPrefetching</code> app-wide or <code>prefetch = 'partial'</code> on the segment. The <a href=\"/docs/messages/instant-link-prefetch-partial\">dev warning Insight</a> covers each fix in detail.</p>\n</blockquote>\n<h2 id=\"per-segment-overrides\" data-docs-heading=\"\">Per-segment overrides<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#per-segment-overrides\"><span></span></a></h2>\n<p>A segment that exports an explicit <a href=\"/docs/app/api-reference/file-conventions/route-segment-config/prefetch\"><code>prefetch</code></a> value overrides the app-level default for that route.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Change</th></tr></thead><tbody><tr><td>16.3.0</td><td><code>partialPrefetching</code> introduced. Requires <code>cacheComponents</code> to be enabled.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references and guides.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheComponents</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the cacheComponents flag in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/file-conventions/route-segment-config/prefetch\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">prefetch</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API reference for the prefetch route segment config.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/link\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Link Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable fast client-side navigation with the built-in `next/link` component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/guides/optimizing-prefetching\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Optimizing prefetching</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Resolve per-link URL data with the prefetch prop, or include session data in the App Shell.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/poweredByHeader",
    "title": "next.config.js: poweredByHeader | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">poweredByHeader</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>By default Next.js will add the <code>x-powered-by</code> header. To opt-out of it, open <code>next.config.js</code> and disable the <code>poweredByHeader</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  poweredByHeader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/prefetchInlining",
    "title": "next.config.js: prefetchInlining | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">prefetchInlining<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 15, 2026</div><p>When the App Router prefetches a route, it can bundle small segment responses into a single response instead of requesting each one separately. This reduces the number of prefetch requests at the cost of duplicating some shared segment data across routes. This behavior is on by default, and most apps should leave it that way.</p>\n<p>The <code>experimental.prefetchInlining</code> option lets you override this behavior or disable inlining while debugging navigation issues or measuring request volume. For most applications, there is no need to change the default behavior.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: The inlining behavior is a permanent part of the App Router. Only the <code>experimental.prefetchInlining</code> configuration is experimental, so its options may still change.</p>\n</blockquote>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>To turn off prefetch inlining, set <code>experimental.prefetchInlining</code> to <code>false</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    prefetchInlining</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>To override the thresholds instead of disabling inlining, pass an object. Any value you omit keeps its default:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    prefetchInlining</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      maxSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 2048</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      maxBundleSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 10240</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Value</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>true</code></td><td>Inlines prefetch responses with the default thresholds. This is the default.</td></tr><tr><td><code>false</code></td><td>Disables prefetch inlining. Each segment is prefetched as its own request.</td></tr><tr><td><code>object</code></td><td>Inlines prefetch responses using the <code>maxSize</code> or <code>maxBundleSize</code> you set.</td></tr></tbody></table></div>\n<p>When you pass an object, the following options control the thresholds. Both are measured in bytes of the gzip-compressed segment response:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Default</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>maxSize</code></td><td><code>number</code></td><td><code>2048</code></td><td>Largest a single segment response can be to still be eligible for inlining.</td></tr><tr><td><code>maxBundleSize</code></td><td><code>number</code></td><td><code>10240</code></td><td>Largest total size that can be inlined into one bundled prefetch response along a path.</td></tr></tbody></table></div>\n<p>Lower thresholds keep more per-segment deduplication; higher thresholds inline more data and cut request count further.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Change</th></tr></thead><tbody><tr><td>16.3.0</td><td><code>experimental.prefetchInlining</code> enabled by default.</td></tr><tr><td>16.2.0</td><td><code>experimental.prefetchInlining</code> added.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references and guides.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/components/link\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Link Component</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Enable fast client-side navigation with the built-in `next/link` component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/guides/prefetching\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Prefetching</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to configure prefetching in Next.js</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/productionBrowserSourceMaps",
    "title": "next.config.js: productionBrowserSourceMaps | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">productionBrowserSourceMaps</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>Source Maps are enabled by default during development. During production builds, they are disabled to prevent you leaking your source on the client, unless you specifically opt-in with the configuration flag.</p>\n<p>Next.js provides a configuration flag you can use to enable browser source map generation during the production build:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  productionBrowserSourceMaps</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>When the <code>productionBrowserSourceMaps</code> option is enabled, the source maps will be output in the same directory as the JavaScript files. Next.js will automatically serve these files when requested.</p>\n<ul>\n<li>Adding source maps can increase <code>next build</code> time</li>\n<li>Increases memory usage during <code>next build</code></li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/proxyClientMaxBodySize",
    "title": "next.config.js: proxyClientMaxBodySize | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">proxyClientMaxBodySize<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 20, 2025</div><p>When proxy is used, Next.js automatically clones the request body and buffers it in memory to enable multiple reads - both in proxy and the underlying route handler. To prevent excessive memory usage, this configuration option sets a size limit on the buffered body.</p>\n<p>By default, the maximum body size is <strong>10MB</strong>. If a request body exceeds this limit, the body will only be buffered up to the limit, and a warning will be logged indicating which route exceeded the limit.</p>\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<h3 id=\"string-format-recommended\" data-docs-heading=\"\">String format (recommended)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#string-format-recommended\"><span></span></a></h3>\n<p>Specify the size using a human-readable string format:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    proxyClientMaxBodySize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '1mb'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>Supported units: <code>b</code>, <code>kb</code>, <code>mb</code>, <code>gb</code></p>\n<h3 id=\"number-format\" data-docs-heading=\"\">Number format<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#number-format\"><span></span></a></h3>\n<p>Alternatively, specify the size in bytes as a number:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    proxyClientMaxBodySize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1048576</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // 1MB in bytes</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"behavior\" data-docs-heading=\"\">Behavior<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#behavior\"><span></span></a></h2>\n<p>When a request body exceeds the configured limit:</p>\n<ol>\n<li>Next.js will buffer only the first N bytes (up to the limit)</li>\n<li>A warning will be logged to the console indicating the route that exceeded the limit</li>\n<li>The request will continue processing normally, but only the partial body will be available</li>\n<li>The request will <strong>not</strong> fail or return an error to the client</li>\n</ol>\n<p>If your application needs to process the full request body, you should either:</p>\n<ul>\n<li>Increase the <code>proxyClientMaxBodySize</code> limit</li>\n<li>Handle the partial body gracefully in your application logic</li>\n</ul>\n<h2 id=\"example\" data-docs-heading=\"\">Example<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#example\"><span></span></a></h2>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">proxy.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { NextRequest</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> NextResponse } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> proxy</span><span style=\"color:var(--shiki-color-text)\">(request</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextRequest</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Next.js automatically buffers the body with the configured size limit</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // You can read the body in proxy...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> body</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-token-function)\">.text</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // If the body exceeded the limit, only partial data will be available</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Body size:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> body</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.next</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/api/upload/route.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { NextRequest</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> NextResponse } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> POST</span><span style=\"color:var(--shiki-color-text)\">(request</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextRequest</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // ...and the body is still available in your route handler</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> body</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-token-function)\">.text</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'Body in route handler:'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> body</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.json</span><span style=\"color:var(--shiki-color-text)\">({ received</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> body</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">length</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"good-to-know\" data-docs-heading=\"\">Good to know<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#good-to-know\"><span></span></a></h2>\n<ul>\n<li>This setting only applies when proxy is used in your application</li>\n<li>The default limit of 10MB is designed to balance memory usage and typical use cases</li>\n<li>The limit applies per-request, not globally across all concurrent requests</li>\n<li>For applications handling large file uploads, consider increasing the limit accordingly</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/reactCompiler",
    "title": "next.config.js: reactCompiler | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">reactCompiler</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->February 11, 2026</div><p>Next.js includes support for the <a href=\"https://react.dev/learn/react-compiler/introduction\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">React Compiler<span class=\"inline-flex not-prose\"></span></a>, a tool designed to improve performance by automatically optimizing component rendering. This reduces the need for manual memoization using <code>useMemo</code> and <code>useCallback</code>.</p>\n<p>Next.js includes a custom performance optimization written in SWC that makes the React Compiler more efficient. Instead of running the compiler on every file, Next.js analyzes your project and only applies the React Compiler to relevant files. This avoids unnecessary work and leads to faster builds compared to using the Babel plugin on its own.</p>\n<h2 id=\"how-it-works\" data-docs-heading=\"\">How It Works<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-it-works\"><span></span></a></h2>\n<p>The React Compiler runs through a Babel plugin. To keep builds fast, Next.js uses a custom SWC optimization that only applies the React Compiler to relevant files—like those with JSX or React Hooks.</p>\n<p>This avoids compiling everything and keeps the performance cost minimal. You may still see slightly slower builds compared to the default Rust-based compiler, but the impact is small and localized.</p>\n<p>To use it, install the <code>babel-plugin-react-compiler</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_a9motbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_a9motbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_i9motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_i9motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_q9motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_q9motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_129motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_129motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> babel-plugin-react-compiler</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>Then, add <code>reactCompiler</code> option in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  reactCompiler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"annotations\" data-docs-heading=\"\">Annotations<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#annotations\"><span></span></a></h2>\n<p>You can configure the compiler to run in \"opt-in\" mode as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  reactCompiler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    compilationMode</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'annotation'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>Then, you can annotate specific components or hooks with the <code>\"use memo\"</code> directive from React to opt-in:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use memo'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // ...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Note:</strong> You can also use the <code>\"use no memo\"</code> directive from React for the opposite effect, to opt-out a component or hook.</p>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/reactMaxHeadersLength",
    "title": "next.config.js: reactMaxHeadersLength | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">reactMaxHeadersLength</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 3, 2026</div><p>During prerendering, React can emit headers that can be added to the response. These can be used to improve performance by allowing the browser to preload resources like fonts, scripts, and stylesheets. The default value is <code>6000</code>, but you can override this value by configuring the <code>reactMaxHeadersLength</code> option in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  reactMaxHeadersLength</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This option is only available in App Router.</p>\n</blockquote>\n<p>Depending on the type of proxy between the browser and the server, the headers can be truncated. For example, if you are using a reverse proxy that doesn't support long headers, you should set a lower value to ensure that the headers are not truncated.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/reactStrictMode",
    "title": "next.config.js: reactStrictMode | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">reactStrictMode</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Since Next.js 13.5.1, Strict Mode is <code>true</code> by default with <code>app</code> router, so the above configuration is only necessary for <code>pages</code>. You can still disable Strict Mode by setting <code>reactStrictMode: false</code>.</p>\n</blockquote>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Suggested</strong>: We strongly suggest you enable Strict Mode in your Next.js application to better prepare your application for the future of React.</p>\n</blockquote>\n<p>React's <a href=\"https://react.dev/reference/react/StrictMode\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Strict Mode<span class=\"inline-flex not-prose\"></span></a> is a development mode only feature for highlighting potential problems in an application. It helps to identify unsafe lifecycles, legacy API usage, and a number of other features.</p>\n<p>The Next.js runtime is Strict Mode-compliant. To opt-in to Strict Mode, configure the following option in your <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  reactStrictMode</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If you or your team are not ready to use Strict Mode in your entire application, that's OK! You can incrementally migrate on a page-by-page basis using <code>&lt;React.StrictMode&gt;</code>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/redirects",
    "title": "next.config.js: redirects | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">redirects</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 30, 2026</div>\n<p>Redirects allow you to redirect an incoming request path to a different destination path.</p>\n<p>To use redirects you can use the <code>redirects</code> key in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p><code>redirects</code> can be defined as a synchronous or async function. It should return, or resolve to, an array of objects with <code>source</code>, <code>destination</code>, and <code>permanent</code> properties:</p>\n<ul>\n<li><code>source</code> is the incoming request path pattern.</li>\n<li><code>destination</code> is the path you want to route to.</li>\n<li><code>permanent</code> <code>true</code> or <code>false</code> - if <code>true</code> will use the 308 status code which instructs clients/search engines to cache the redirect forever, if <code>false</code> will use the 307 status code which is temporary and is not cached.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Why does Next.js use 307 and 308?</strong> Traditionally a 302 was used for a temporary redirect, and a 301 for a permanent redirect, but many browsers changed the request method of the redirect to <code>GET</code>, regardless of the original method. For example, if the browser made a request to <code>POST /v1/users</code> which returned status code <code>302</code> with location <code>/v2/users</code>, the subsequent request might be <code>GET /v2/users</code> instead of the expected <code>POST /v2/users</code>. Next.js uses the 307 temporary redirect, and 308 permanent redirect status codes to explicitly preserve the request method used.</p>\n</blockquote>\n<ul>\n<li><code>basePath</code>: <code>false</code> or <code>undefined</code> - if false the <code>basePath</code> won't be included when matching, can be used for external redirects only.</li>\n<li><code>locale</code>: <code>false</code> or <code>undefined</code> - whether the locale should not be included when matching.</li>\n<li><code>has</code> is an array of <a href=\"#header-cookie-and-query-matching\">has objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n<li><code>missing</code> is an array of <a href=\"#header-cookie-and-query-matching\">missing objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n</ul>\n<p>Redirects are checked before the filesystem which includes pages and <code>/public</code> files.</p>\n<p>When using the Pages Router, redirects are not applied to client-side routing (<code>Link</code>, <code>router.push</code>) unless <a href=\"/docs/app/api-reference/file-conventions/proxy\">Proxy</a> is present and matches the path.</p>\n<p>When a redirect is applied, any query values provided in the request will be passed through to the redirect destination. For example, see the following redirect configuration:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  source</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/old-blog/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  destination</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  permanent</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Remember to include the forward slash <code>/</code> before the colon <code>:</code> in path parameters of the <code>source</code> and <code>destination</code> paths, otherwise the path will be treated as a literal string and you run the risk of causing infinite redirects.</p>\n</blockquote>\n<p>When <code>/old-blog/post-1?hello=world</code> is requested, the client will be redirected to <code>/blog/post-1?hello=world</code>.</p>\n<h2 id=\"path-matching\" data-docs-heading=\"\">Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#path-matching\"><span></span></a></h2>\n<p>Path matches are allowed, for example <code>/old-blog/:slug</code> will match <code>/old-blog/first-post</code> (no nested paths):</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/old-blog/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/news/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The pattern <code>/old-blog/:slug</code> matches <code>/old-blog/first-post</code> and <code>/old-blog/post-1</code> but not <code>/old-blog/a/b</code> (no nested paths). Patterns are anchored to the start: <code>/old-blog/:slug</code> will not match <code>/archive/old-blog/first-post</code>.</p>\n<p>You can use modifiers on parameters: <code>*</code> (zero or more), <code>+</code> (one or more), <code>?</code> (zero or one). For example, <code>/blog/:slug*</code> matches <code>/blog</code>, <code>/blog/a</code>, and <code>/blog/a/b/c</code>.</p>\n<p>Read more details on <a href=\"https://github.com/pillarjs/path-to-regexp\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">path-to-regexp<span class=\"inline-flex not-prose\"></span></a> documentation.</p>\n<h3 id=\"wildcard-path-matching\" data-docs-heading=\"\">Wildcard Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#wildcard-path-matching\"><span></span></a></h3>\n<p>To match a wildcard path you can use <code>*</code> after a parameter, for example <code>/blog/:slug*</code> will match <code>/blog/a/b/c/d/hello-world</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/news/:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"regex-path-matching\" data-docs-heading=\"\">Regex Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#regex-path-matching\"><span></span></a></h3>\n<p>To match a regex path you can wrap the regex in parentheses after a parameter, for example <code>/post/:slug(\\\\d{1,})</code> will match <code>/post/123</code> but not <code>/post/abc</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/post/:slug(\\\\d{1,})'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/news/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The following characters <code>(</code>, <code>)</code>, <code>{</code>, <code>}</code>, <code>:</code>, <code>*</code>, <code>+</code>, <code>?</code> are used for regex path matching, so when used in the <code>source</code> as non-special values they must be escaped by adding <code>\\\\</code> before them:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // this will match `/english(default)/something` being requested</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/english\\\\(default\\\\)/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en-us/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"header-cookie-and-query-matching\" data-docs-heading=\"\">Header, Cookie, and Query Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#header-cookie-and-query-matching\"><span></span></a></h2>\n<p>To only match a redirect when header, cookie, or query values also match the <code>has</code> field or don't match the <code>missing</code> field can be used. Both the <code>source</code> and all <code>has</code> items must match and all <code>missing</code> items must not match for the redirect to be applied.</p>\n<p><code>has</code> and <code>missing</code> items can have the following fields:</p>\n<ul>\n<li><code>type</code>: <code>String</code> - must be either <code>header</code>, <code>cookie</code>, <code>host</code>, or <code>query</code>.</li>\n<li><code>key</code>: <code>String</code> - the key from the selected type to match against.</li>\n<li><code>value</code>: <code>String</code> or <code>undefined</code> - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value <code>first-(?&lt;paramName&gt;.*)</code> is used for <code>first-second</code> then <code>second</code> will be usable in the destination with <code>:paramName</code>.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-redirect-me` is present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this redirect will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path((?!another-page$).*)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-redirect-me'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-do-not-redirect` is present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this redirect will NOT be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path((?!another-page$).*)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        missing</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-do-not-redirect'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the source, query, and cookie are matched,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this redirect will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/specific/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'query'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // the page value will not be available in the</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // destination since value is provided and doesn't</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // use a named capture group e.g. (?&lt;page&gt;home)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'home'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'cookie'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'true'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-authorized` is present and</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // contains a matching value, this redirect will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '(?&lt;authorized&gt;yes|true)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/home?authorized=:authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the host is `example.com`,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this redirect will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path((?!another-page$).*)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'host'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"redirects-with-basepath-support\" data-docs-heading=\"\">Redirects with basePath support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#redirects-with-basepath-support\"><span></span></a></h3>\n<p>When leveraging <a href=\"/docs/app/api-reference/config/next-config-js/basePath\"><code>basePath</code> support</a> with redirects each <code>source</code> and <code>destination</code> is automatically prefixed with the <code>basePath</code> unless you add <code>basePath: false</code> to the redirect:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/docs'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/with-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // automatically becomes /docs/with-basePath</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // automatically becomes /docs/another</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // does not add /docs since basePath: false is set</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/without-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"redirects-with-i18n-support\" data-docs-heading=\"\">Redirects with i18n support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#redirects-with-i18n-support\"><span></span></a></h3>\n<p>When implementing redirects with internationalization in the App Router, you can include locales in <code>next.config.js</code> redirects, but only as hardcoded paths.</p><p>For dynamic or per-request locale handling, use <a href=\"/docs/app/guides/internationalization\">dynamic route segments and proxy</a>, which can redirect based on the user's preferred language.</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  redirects</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Manually handle locale prefixes for App Router</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en/old-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en/new-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Redirect for all locales using a parameter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:locale/old-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:locale/new-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Redirect from one locale to another</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/de/old-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en/new-path'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Catch-all redirect for multiple locales</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:locale(en|fr|de)/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:locale/new-section/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        permanent</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use the <code>statusCode</code> property instead of the <code>permanent</code> property, but not both. To ensure IE11 compatibility, a <code>Refresh</code> header is automatically added for the 308 status code.</p>\n<h2 id=\"other-redirects\" data-docs-heading=\"\">Other Redirects<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#other-redirects\"><span></span></a></h2>\n<ul>\n<li>Inside <a href=\"/docs/pages/building-your-application/routing/api-routes\">API Routes</a> and <a href=\"/docs/app/api-reference/file-conventions/route\">Route Handlers</a>, you can redirect based on the incoming request.</li>\n<li>Inside <a href=\"/docs/pages/building-your-application/data-fetching/get-static-props\"><code>getStaticProps</code></a> and <a href=\"/docs/pages/building-your-application/data-fetching/get-server-side-props\"><code>getServerSideProps</code></a>, you can redirect specific pages at request-time.</li>\n</ul>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.3.0</code></td><td><code>missing</code> added.</td></tr><tr><td><code>v10.2.0</code></td><td><code>has</code> added.</td></tr><tr><td><code>v9.5.0</code></td><td><code>redirects</code> added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/rewrites",
    "title": "next.config.js: rewrites | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">rewrites</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 30, 2026</div>\n<p>Rewrites allow you to map an incoming request path to a different destination path.</p>\n<p>Rewrites act as a URL proxy and mask the destination path, making it appear the user hasn't changed their location on the site. In contrast, <a href=\"/docs/app/api-reference/config/next-config-js/redirects\">redirects</a> will reroute to a new page and show the URL changes.</p>\n<!-- -->\n<p>To use rewrites you can use the <code>rewrites</code> key in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Rewrites are applied to client-side routing. In the example above, navigating to <code>&lt;Link href=\"/about\"&gt;</code> will serve content from <code>/</code> while keeping the URL as <code>/about</code>.</p>\n<p><code>rewrites</code> can be defined as a synchronous or async function. It should return, or resolve to, either an array or an object of arrays (see below) holding objects with <code>source</code> and <code>destination</code> properties:</p>\n<ul>\n<li><code>source</code>: <code>String</code> - is the incoming request path pattern.</li>\n<li><code>destination</code>: <code>String</code> is the path you want to route to.</li>\n<li><code>basePath</code>: <code>false</code> or <code>undefined</code> - if false the basePath won't be included when matching, can be used for external rewrites only.</li>\n<li><code>locale</code>: <code>false</code> or <code>undefined</code> - whether the locale should not be included when matching.</li>\n<li><code>has</code> is an array of <a href=\"#header-cookie-and-query-matching\">has objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n<li><code>missing</code> is an array of <a href=\"#header-cookie-and-query-matching\">missing objects</a> with the <code>type</code>, <code>key</code> and <code>value</code> properties.</li>\n</ul>\n<p>When the <code>rewrites</code> function returns an array, rewrites are applied after checking the filesystem (pages and <code>/public</code> files) and before dynamic routes. When the <code>rewrites</code> function returns an object of arrays with a specific shape, this behavior can be changed and more finely controlled, as of <code>v10.1</code> of Next.js:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      beforeFiles</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // These rewrites are checked after headers/redirects</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // and before all files including _next/public files which</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // allows overriding page files</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/some-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/somewhere-else'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [{ type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'query'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'overrideMe'</span><span style=\"color:var(--shiki-color-text)\"> }]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      afterFiles</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // These rewrites are checked after pages/public files</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // are checked but before dynamic routes</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/non-existent'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/somewhere-else'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      fallback</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // These rewrites are checked after both pages/public files</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // and dynamic routes are checked</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://my-old-site.com/:path*`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: rewrites in <code>beforeFiles</code> do not check the filesystem/dynamic routes immediately after matching a source, they continue until all <code>beforeFiles</code> have been checked.</p>\n</blockquote>\n<p>The order Next.js routes are checked is:</p>\n<ol>\n<li><a href=\"/docs/app/api-reference/config/next-config-js/headers\">headers</a> are checked/applied</li>\n<li><a href=\"/docs/app/api-reference/config/next-config-js/redirects\">redirects</a> are checked/applied</li>\n<li><a href=\"/docs/app/api-reference/file-conventions/proxy\">proxy</a></li>\n<li><code>beforeFiles</code> rewrites: for each entry, if <code>source</code>, <code>has</code>, and <code>missing</code> matches the request, it's rewritten to <code>destination</code>.</li>\n<li>static files from the <a href=\"/docs/app/api-reference/file-conventions/public-folder\">public directory</a>, <code>_next/static</code> files, and non-dynamic pages are checked/served</li>\n<li><code>afterFiles</code> rewrites are tried in order. If a <code>source</code>, <code>has</code>, and <code>missing</code> matches the request, it's rewritten to <code>destination</code>; the first rewrite that resolves to a static file, page, or dynamic route is served.</li>\n<li>dynamic routes (e.g., <code>app/blog/[slug]/page.tsx</code>) are matched against the current path</li>\n<li><code>fallback</code> rewrites are checked/applied, these are applied before rendering the 404 page and after dynamic routes/all static assets have been checked. If you use <a href=\"/docs/pages/api-reference/functions/get-static-paths#fallback-true\">fallback: true/'blocking'</a> in <code>getStaticPaths</code>, those dynamic routes take priority over the fallback <code>rewrites</code> defined in your <code>next.config.js</code>.</li>\n</ol>\n<!-- -->\n<h2 id=\"rewrite-parameters\" data-docs-heading=\"\">Rewrite parameters<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#rewrite-parameters\"><span></span></a></h2>\n<p>When using parameters in a rewrite the parameters will be passed in the query by default when none of the parameters are used in the <code>destination</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/old-about/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // The :path parameter isn't used here so will be automatically passed in the query</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If a parameter is used in the destination none of the parameters will be automatically passed in the query.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/docs/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // The :path parameter is used here so will not be automatically passed in the query</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can still pass the parameters manually in the query if one is already used in the destination by specifying the query in the <code>destination</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:first/:second'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:first?second=:second'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Since the :first parameter is used in the destination the :second parameter</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // will not automatically be added in the query although we can manually add it</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // as shown above</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Static pages from <a href=\"/docs/pages/building-your-application/rendering/automatic-static-optimization\">Automatic Static Optimization</a> or <a href=\"/docs/pages/building-your-application/data-fetching/get-static-props\">prerendering</a> params from rewrites will be parsed on the client after hydration and provided in the query.</p>\n</blockquote>\n<h2 id=\"path-matching\" data-docs-heading=\"\">Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#path-matching\"><span></span></a></h2>\n<p>Path matches are allowed, for example <code>/blog/:slug</code> will match <code>/blog/first-post</code> (no nested paths):</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/news/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The pattern <code>/blog/:slug</code> matches <code>/blog/first-post</code> and <code>/blog/post-1</code> but not <code>/blog/a/b</code> (no nested paths). Patterns are anchored to the start: <code>/blog/:slug</code> will not match <code>/archive/blog/first-post</code>.</p>\n<p>You can use modifiers on parameters: <code>*</code> (zero or more), <code>+</code> (one or more), <code>?</code> (zero or one). For example, <code>/blog/:slug*</code> matches <code>/blog</code>, <code>/blog/a</code>, and <code>/blog/a/b/c</code>.</p>\n<p>Read more details on <a href=\"https://github.com/pillarjs/path-to-regexp\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">path-to-regexp<span class=\"inline-flex not-prose\"></span></a> documentation.</p>\n<h3 id=\"wildcard-path-matching\" data-docs-heading=\"\">Wildcard Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#wildcard-path-matching\"><span></span></a></h3>\n<p>To match a wildcard path you can use <code>*</code> after a parameter, for example <code>/blog/:slug*</code> will match <code>/blog/a/b/c/d/hello-world</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/news/:slug*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"regex-path-matching\" data-docs-heading=\"\">Regex Path Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#regex-path-matching\"><span></span></a></h3>\n<p>To match a regex path you can wrap the regex in parenthesis after a parameter, for example <code>/blog/:slug(\\\\d{1,})</code> will match <code>/blog/123</code> but not <code>/blog/abc</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/old-blog/:post(\\\\d{1,})'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:post'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The following characters <code>(</code>, <code>)</code>, <code>{</code>, <code>}</code>, <code>[</code>, <code>]</code>, <code>|</code>, <code>\\</code>, <code>^</code>, <code>.</code>, <code>:</code>, <code>*</code>, <code>+</code>, <code>-</code>, <code>?</code>, <code>$</code> are used for regex path matching, so when used in the <code>source</code> as non-special values they must be escaped by adding <code>\\\\</code> before them:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // this will match `/english(default)/something` being requested</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/english\\\\(default\\\\)/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/en-us/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"header-cookie-and-query-matching\" data-docs-heading=\"\">Header, Cookie, and Query Matching<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#header-cookie-and-query-matching\"><span></span></a></h2>\n<p>To only match a rewrite when header, cookie, or query values also match the <code>has</code> field or don't match the <code>missing</code> field can be used. Both the <code>source</code> and all <code>has</code> items must match and all <code>missing</code> items must not match for the rewrite to be applied.</p>\n<p><code>has</code> and <code>missing</code> items can have the following fields:</p>\n<ul>\n<li><code>type</code>: <code>String</code> - must be either <code>header</code>, <code>cookie</code>, <code>host</code>, or <code>query</code>.</li>\n<li><code>key</code>: <code>String</code> - the key from the selected type to match against.</li>\n<li><code>value</code>: <code>String</code> or <code>undefined</code> - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value <code>first-(?&lt;paramName&gt;.*)</code> is used for <code>first-second</code> then <code>second</code> will be usable in the destination with <code>:paramName</code>.</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-rewrite-me` is present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this rewrite will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-rewrite-me'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-rewrite-me` is not present,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this rewrite will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        missing</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-rewrite-me'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the source, query, and cookie are matched,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this rewrite will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/specific/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'query'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // the page value will not be available in the</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // destination since value is provided and doesn't</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // use a named capture group e.g. (?&lt;page&gt;home)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'home'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'cookie'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'true'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*/home'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the header `x-authorized` is present and</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // contains a matching value, this rewrite will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'header'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            key</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'x-authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '(?&lt;authorized&gt;yes|true)'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/home?authorized=:authorized'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // if the host is `example.com`,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // this rewrite will be applied</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        has</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'host'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            value</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another-page'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"rewriting-to-an-external-url\" data-docs-heading=\"\">Rewriting to an external URL<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#rewriting-to-an-external-url\"><span></span></a></h2>\n<details><summary>Examples</summary><ul>\n<li><a href=\"https://github.com/vercel/next.js/tree/canary/examples/with-zones\" rel=\"noopener noreferrer\" target=\"_blank\">Using Multiple Zones<span class=\"inline-flex not-prose\"></span></a></li>\n</ul></details>\n<p>Rewrites allow you to rewrite to an external URL. This is especially useful for incrementally adopting Next.js. The following is an example rewrite for redirecting the <code>/blog</code> route of your main app to an external site.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/blog'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/blog/:slug'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // Matched parameters can be used in the destination</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If you're using <code>trailingSlash: true</code>, you also need to insert a trailing slash in the <code>source</code> parameter. If the destination server is also expecting a trailing slash it should be included in the <code>destination</code> parameter as well.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  trailingSlash</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/blog/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog/:path*/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/blog/:path*/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"incremental-adoption-of-nextjs\" data-docs-heading=\"\">Incremental adoption of Next.js<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#incremental-adoption-of-nextjs\"><span></span></a></h3>\n<p>You can also have Next.js fall back to proxying to an existing website after checking all Next.js routes.</p>\n<p>This way you don't have to change the rewrites configuration when migrating more pages to Next.js</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      fallback</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/:path*'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> `https://custom-routes-proxying-endpoint.vercel.app/:path*`</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"rewrites-with-basepath-support\" data-docs-heading=\"\">Rewrites with basePath support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#rewrites-with-basepath-support\"><span></span></a></h3>\n<p>When leveraging <a href=\"/docs/app/api-reference/config/next-config-js/basePath\"><code>basePath</code> support</a> with rewrites each <code>source</code> and <code>destination</code> is automatically prefixed with the <code>basePath</code> unless you add <code>basePath: false</code> to the rewrite:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/docs'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  rewrites</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/with-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // automatically becomes /docs/with-basePath</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/another'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // automatically becomes /docs/another</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // does not add /docs to /without-basePath since basePath: false is set</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">        // Note: this cannot be used for internal rewrites e.g. `destination: '/another'`</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        source</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/without-basePath'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        destination</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        basePath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.3.0</code></td><td><code>missing</code> added.</td></tr><tr><td><code>v10.2.0</code></td><td><code>has</code> added.</td></tr><tr><td><code>v9.5.0</code></td><td>Headers added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/sassOptions",
    "title": "next.config.js: sassOptions | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">sassOptions</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 19, 2025</div><p><code>sassOptions</code> allow you to configure the Sass compiler.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> sassOptions</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  additionalData</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> `</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    $var: red;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  `</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  sassOptions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    ...</span><span style=\"color:var(--shiki-color-text)\">sassOptions</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    implementation</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'sass-embedded'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong></p>\n<ul>\n<li><code>sassOptions</code> are not typed outside of <code>implementation</code> because Next.js does not maintain the other possible properties.</li>\n<li>The <code>functions</code> property for defining custom Sass functions is only supported with webpack. When using Turbopack, custom Sass functions are not available because Turbopack's Rust-based architecture cannot directly execute JavaScript functions passed through this option.</li>\n</ul>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/serverActions",
    "title": "next.config.js: serverActions | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">serverActions</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 25, 2026</div><p>Options for configuring Server Actions behavior in your Next.js application. For how Server Actions work, including the security boundary these options tune, see the <a href=\"/docs/app/guides/server-actions\">Server Actions guide</a>.</p>\n<h2 id=\"allowedorigins\" data-docs-heading=\"\"><code>allowedOrigins</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#allowedorigins\"><span></span></a></h2>\n<p>A list of extra safe origin domains from which Server Actions can be invoked. Next.js compares the origin of a Server Action request with the host domain, ensuring they match to prevent CSRF attacks. If not provided, only the same origin is allowed.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    serverActions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      allowedOrigins</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'my-proxy.com'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.my-proxy.com'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"bodysizelimit\" data-docs-heading=\"\"><code>bodySizeLimit</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#bodysizelimit\"><span></span></a></h2>\n<p>By default, the maximum size of the request body sent to a Server Action is 1MB, to prevent the consumption of excessive server resources in parsing large amounts of data, as well as potential DDoS attacks.</p>\n<p>However, you can configure this limit using the <code>serverActions.bodySizeLimit</code> option. It can take the number of bytes or any string format supported by bytes, for example <code>1000</code>, <code>'500kb'</code> or <code>'3mb'</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    serverActions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      bodySizeLimit</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '2mb'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The limit applies to the raw HTTP request body, including the bytes that <code>multipart/form-data</code> adds for boundaries, part headers, and field metadata. If you expect uploads close to the configured value, leave some room for this overhead. For typical multipart uploads, an additional 10–20 KB is a reasonable rule of thumb.</p>\n<h2 id=\"enabling-server-actions-v13\" data-docs-heading=\"\">Enabling Server Actions (v13)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#enabling-server-actions-v13\"><span></span></a></h2>\n<p>Server Actions became a stable feature in Next.js 14, and are enabled by default. However, if you are using an earlier version of Next.js, you can enable them by setting <code>experimental.serverActions</code> to <code>true</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    serverActions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> config</span></span></code></pre></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" data-docs-heading=\"\"></h2><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/guides/server-actions\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Server Actions</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">How Server Actions work in Next.js, including the single-roundtrip response model, sequential dispatch, security, and caching integration.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/serverComponentsHmrCache",
    "title": "next.config.js: serverComponentsHmrCache | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">serverComponentsHmrCache<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><p>The experimental <code>serverComponentsHmrCache</code> option allows you to cache <code>fetch</code> responses in Server Components across Hot Module Replacement (HMR) refreshes in local development. This results in faster responses and reduced costs for billed API calls.</p>\n<p>By default, the HMR cache applies to all <code>fetch</code> requests, including those with the <code>cache: 'no-store'</code> option. This means uncached requests will not show fresh data between HMR refreshes. However, the cache will be cleared on navigation or full-page reloads.</p>\n<p>You can disable the HMR cache by setting <code>serverComponentsHmrCache</code> to <code>false</code> in your <code>next.config.js</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    serverComponentsHmrCache</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // defaults to true</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> For better observability, we recommend using the <a href=\"/docs/app/api-reference/config/next-config-js/logging\"><code>logging.fetches</code></a> option which logs fetch cache hits and misses in the console during development.</p>\n</blockquote></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/serverExternalPackages",
    "title": "next.config.js: serverExternalPackages | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">serverExternalPackages</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->December 5, 2025</div><p>Dependencies used inside <a href=\"/docs/app/getting-started/server-and-client-components\">Server Components</a> and <a href=\"/docs/app/api-reference/file-conventions/route\">Route Handlers</a> will automatically be bundled by Next.js.</p>\n<p>If a dependency is using Node.js specific features, you can choose to opt-out specific dependencies from the Server Components bundling and use native Node.js <code>require</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  serverExternalPackages</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'@acme/ui'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>Next.js includes a <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/server-external-packages.jsonc\" rel=\"noopener noreferrer\" target=\"_blank\">short list of popular packages<span class=\"inline-flex not-prose\"></span></a> that currently are working on compatibility and automatically opt-ed out:</p>\n<ul>\n<li><code>@alinea/generated</code></li>\n<li><code>@appsignal/nodejs</code></li>\n<li><code>@aws-sdk/client-s3</code></li>\n<li><code>@aws-sdk/s3-presigned-post</code></li>\n<li><code>@blockfrost/blockfrost-js</code></li>\n<li><code>@highlight-run/node</code></li>\n<li><code>@huggingface/transformers</code></li>\n<li><code>@jpg-store/lucid-cardano</code></li>\n<li><code>@libsql/client</code></li>\n<li><code>@mikro-orm/core</code></li>\n<li><code>@mikro-orm/knex</code></li>\n<li><code>@node-rs/argon2</code></li>\n<li><code>@node-rs/bcrypt</code></li>\n<li><code>@prisma/client</code></li>\n<li><code>@react-pdf/renderer</code></li>\n<li><code>@sentry/profiling-node</code></li>\n<li><code>@sparticuz/chromium</code></li>\n<li><code>@sparticuz/chromium-min</code></li>\n<li><code>@statsig/statsig-node-core</code></li>\n<li><code>@swc/core</code></li>\n<li><code>@xenova/transformers</code></li>\n<li><code>@zenstackhq/runtime</code></li>\n<li><code>argon2</code></li>\n<li><code>autoprefixer</code></li>\n<li><code>aws-crt</code></li>\n<li><code>bcrypt</code></li>\n<li><code>better-sqlite3</code></li>\n<li><code>canvas</code></li>\n<li><code>chromadb-default-embed</code></li>\n<li><code>config</code></li>\n<li><code>cpu-features</code></li>\n<li><code>cypress</code></li>\n<li><code>dd-trace</code></li>\n<li><code>eslint</code></li>\n<li><code>express</code></li>\n<li><code>firebase-admin</code></li>\n<li><code>htmlrewriter</code></li>\n<li><code>import-in-the-middle</code></li>\n<li><code>isolated-vm</code></li>\n<li><code>jest</code></li>\n<li><code>jsdom</code></li>\n<li><code>keyv</code></li>\n<li><code>libsql</code></li>\n<li><code>mdx-bundler</code></li>\n<li><code>mongodb</code></li>\n<li><code>mongoose</code></li>\n<li><code>newrelic</code></li>\n<li><code>next-mdx-remote</code></li>\n<li><code>next-seo</code></li>\n<li><code>node-cron</code></li>\n<li><code>node-pty</code></li>\n<li><code>node-web-audio-api</code></li>\n<li><code>onnxruntime-node</code></li>\n<li><code>oslo</code></li>\n<li><code>pg</code></li>\n<li><code>pino</code></li>\n<li><code>pino-pretty</code></li>\n<li><code>pino-roll</code></li>\n<li><code>playwright</code></li>\n<li><code>playwright-core</code></li>\n<li><code>postcss</code></li>\n<li><code>prettier</code></li>\n<li><code>prisma</code></li>\n<li><code>puppeteer-core</code></li>\n<li><code>puppeteer</code></li>\n<li><code>ravendb</code></li>\n<li><code>require-in-the-middle</code></li>\n<li><code>rimraf</code></li>\n<li><code>sharp</code></li>\n<li><code>shiki</code></li>\n<li><code>sqlite3</code></li>\n<li><code>thread-stream</code></li>\n<li><code>ts-morph</code></li>\n<li><code>ts-node</code></li>\n<li><code>typescript</code></li>\n<li><code>vscode-oniguruma</code></li>\n<li><code>webpack</code></li>\n<li><code>websocket</code></li>\n<li><code>zeromq</code></li>\n</ul>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v15.0.0</code></td><td>Moved from experimental to stable. Renamed from <code>serverComponentsExternalPackages</code> to <code>serverExternalPackages</code></td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/staleTimes",
    "title": "next.config.js: staleTimes | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">staleTimes<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 3, 2026</div><p><code>staleTimes</code> is an experimental feature that enables caching of page segments in the <a href=\"/docs/app/glossary#client-cache\">Client Cache</a>.</p>\n<p>You can enable this experimental feature and provide custom revalidation times by setting the experimental <code>staleTimes</code> flag:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    staleTimes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      dynamic</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 30</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      static</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 180</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>The <code>static</code> and <code>dynamic</code> properties correspond with the time period (in seconds) based on different types of <a href=\"/docs/app/api-reference/components/link#prefetch\">link prefetching</a>.</p>\n<ul>\n<li>The <code>dynamic</code> property is used when the page is neither statically generated nor fully prefetched (e.g. with <code>prefetch={true}</code>).<!-- -->\n<ul>\n<li>Default: 0 seconds (not cached)</li>\n</ul>\n</li>\n<li>The <code>static</code> property is used for statically generated pages, or when the <code>prefetch</code> prop on <code>Link</code> is set to <code>true</code>, or when calling <a href=\"/docs/app/api-reference/functions/use-router\"><code>router.prefetch</code></a>.<!-- -->\n<ul>\n<li>Default: 5 minutes</li>\n</ul>\n</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong></p>\n<ul>\n<li><a href=\"/docs/app/api-reference/file-conventions/loading\">Loading boundaries</a> are considered reusable for the <code>static</code> period defined in this configuration.</li>\n<li>This doesn't affect <a href=\"/docs/app/getting-started/linking-and-navigating#client-side-transitions\">partial rendering</a>, <strong>meaning shared layouts won't automatically be refetched on every navigation, only the page segment that changes.</strong></li>\n<li>This doesn't change <a href=\"/docs/app/glossary#client-cache\">back/forward caching</a> behavior to prevent layout shift and to prevent losing the browser scroll position.</li>\n</ul>\n</blockquote>\n<h3 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h3>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v15.0.0</code></td><td>The <code>dynamic</code> <code>staleTimes</code> default changed from 30s to 0s.</td></tr><tr><td><code>v14.2.0</code></td><td>Experimental <code>staleTimes</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/staticGeneration",
    "title": "next.config.js: staticGeneration* | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">staticGeneration*<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><p>The <code>staticGeneration*</code> options allow you to configure the Static Generation process for advanced use cases.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    staticGenerationRetryCount</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 1</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    staticGenerationMaxConcurrency</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 8</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    staticGenerationMinPagesPerWorker</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 25</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"config-options\" data-docs-heading=\"\">Config Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#config-options\"><span></span></a></h2>\n<p>The following options are available:</p>\n<ul>\n<li><code>staticGenerationRetryCount</code>: The number of times to retry a failed page generation before failing the build.</li>\n<li><code>staticGenerationMaxConcurrency</code>: The maximum number of pages to be processed per worker.</li>\n<li><code>staticGenerationMinPagesPerWorker</code>: The minimum number of pages to be processed before starting a new worker.</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/supportsImmutableAssets",
    "title": "next.config.js: supportsImmutableAssets | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">supportsImmutableAssets</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 10, 2026</div><blockquote class=\"p-3 text-sm\">\n<p><strong>Attention</strong>: This option is primarily intended for <a href=\"/docs/app/api-reference/adapters\">adapter</a> authors.\nApp developers should only set it when troubleshooting adapter-specific issues.</p>\n<p><strong>Enabling this feature when your provider or adapter does not support it can result in broken deployments.</strong></p>\n</blockquote>\n<p>When skew protection is enabled, static asset requests include a deployment-specific query parameter, for example:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>GET https://foo.com/_next/static/chunks/0d_ks0ow7ur6m.js?dpl=&lt;unique-deployment-id&gt;</span></span></code></pre></div>\n<p>One downside is that browsers have to download static assets again after each new deployment, even when those assets have not changed.</p>\n<p>Immutable static assets allow the <code>?dpl</code> query parameter to be omitted for static assets that are guaranteed to be immutable and content-addressed by their filename. This lets browsers cache those assets indefinitely and allows unchanged static assets to be skipped when uploading files during subsequent deployments:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>GET https://foo.com/_next/static/immutable/chunks/0d_ks0ow7ur6m.js</span></span></code></pre></div>\n<p>You can use this config option to opt out of immutable static assets when your adapter has enabled support for them. If your adapter has not enabled this feature, this option has no effect:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  supportsImmutableAssets</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>See <a href=\"/docs/app/api-reference/adapters/immutable-static-assets\">Supporting immutable static assets</a> for more information on how to support this feature in an adapter.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td>Added support for immutable static assets.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/taint",
    "title": "next.config.js: taint | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">taint<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>The <code>taint</code> option enables support for experimental React APIs for tainting objects and values. This feature helps prevent sensitive data from being accidentally passed to the client. When enabled, you can use:</p>\n<ul>\n<li><a href=\"https://react.dev/reference/react/experimental_taintObjectReference\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>experimental_taintObjectReference</code><span class=\"inline-flex not-prose\"></span></a> taint objects references.</li>\n<li><a href=\"https://react.dev/reference/react/experimental_taintUniqueValue\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>experimental_taintUniqueValue</code><span class=\"inline-flex not-prose\"></span></a> to taint unique values.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Activating this flag also enables the React <code>experimental</code> channel for <code>app</code> directory.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    taint</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning:</strong> Do not rely on the taint API as your only mechanism to prevent exposing sensitive data to the client. See our <a href=\"/blog/security-nextjs-server-components-actions\">security recommendations</a>.</p>\n</blockquote>\n<p>The taint APIs allows you to be defensive, by declaratively and explicitly marking data that is not allowed to pass through the Server-Client boundary. When an object or value, is passed through the Server-Client boundary, React throws an error.</p>\n<p>This is helpful for cases where:</p>\n<ul>\n<li>The methods to read data are out of your control</li>\n<li>You have to work with sensitive data shapes not defined by you</li>\n<li>Sensitive data is accessed during Server Component rendering</li>\n</ul>\n<p>It is recommended to model your data and APIs so that sensitive data is not returned to contexts where it is not needed.</p>\n<h2 id=\"caveats\" data-docs-heading=\"\">Caveats<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caveats\"><span></span></a></h2>\n<ul>\n<li>Tainting can only keep track of objects by reference. Copying an object creates an untainted version, which loses all guarantees given by the API. You'll need to taint the copy.</li>\n<li>Tainting cannot keep track of data derived from a tainted value. You also need to taint the derived value.</li>\n<li>Values are tainted for as long as their lifetime reference is within scope. See the <a href=\"https://react.dev/reference/react/experimental_taintUniqueValue#parameters\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>experimental_taintUniqueValue</code> parameters reference<span class=\"inline-flex not-prose\"></span></a>, for more information.</li>\n</ul>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"tainting-an-object-reference\" data-docs-heading=\"\">Tainting an object reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#tainting-an-object-reference\"><span></span></a></h3>\n<p>In this case, the <code>getUserDetails</code> function returns data about a given user. We taint the user object reference, so that it cannot cross a Server-Client boundary. For example, assuming <code>UserCard</code> is a Client Component.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { experimental_taintObjectReference } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> getUserDetails</span><span style=\"color:var(--shiki-color-text)\">(id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> UserDetails</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> user</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> db</span><span style=\"color:var(--shiki-token-function)\">.queryUserById</span><span style=\"color:var(--shiki-color-text)\">(id)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  experimental_taintObjectReference</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'Do not use the entire user info object. Instead, select only the fields you need.'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    user</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> user</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>We can still access individual fields from the tainted <code>userDetails</code> object.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> ContactPage</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;{ id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">id</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> params</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> userDetails</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getUserDetails</span><span style=\"color:var(--shiki-color-text)\">(id)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">UserCard</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      firstName</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">userDetails</span><span style=\"color:var(--shiki-color-text)\">.firstName}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">      lastName</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">userDetails</span><span style=\"color:var(--shiki-color-text)\">.lastName}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>Now, passing the entire object to the Client Component will throw an error.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> ContactPage</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;{ id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> userDetails</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getUserDetails</span><span style=\"color:var(--shiki-color-text)\">(id)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Throws an error</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">UserCard</span><span style=\"color:var(--shiki-token-function)\"> user</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{userDetails} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"tainting-a-unique-value\" data-docs-heading=\"\">Tainting a unique value<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#tainting-a-unique-value\"><span></span></a></h3>\n<p>In this case, we can access the server configuration by awaiting calls to <code>config.getConfigDetails</code>. However, the system configuration contains the <code>SERVICE_API_KEY</code> that we don't want to expose to clients.</p>\n<p>We can taint the <code>config.SERVICE_API_KEY</code> value.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { experimental_taintUniqueValue } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> getSystemConfig</span><span style=\"color:var(--shiki-color-text)\">()</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> SystemConfig</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-constant)\"> config</span><span style=\"color:var(--shiki-token-function)\">.getConfigDetails</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  experimental_taintUniqueValue</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'Do not pass configuration tokens to the client'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    config</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">SERVICE_API_KEY</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>We can still access other properties of the <code>systemConfig</code> object.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dashboard</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> systemConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getSystemConfig</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">ClientDashboard</span><span style=\"color:var(--shiki-token-function)\"> version</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">systemConfig</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">SERVICE_API_VERSION</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>However, passing <code>SERVICE_API_KEY</code> to <code>ClientDashboard</code> throws an error.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dashboard</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> systemConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getSystemConfig</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Someone makes a mistake in a PR</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> version</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> systemConfig</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">SERVICE_API_KEY</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">ClientDashboard</span><span style=\"color:var(--shiki-token-function)\"> version</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{version} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Note that, even though, <code>systemConfig.SERVICE_API_KEY</code> is reassigned to a new variable. Passing it to a Client Component still throws an error.</p>\n<p>Whereas, a value derived from a tainted unique value, will be exposed to the client.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dashboard</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> systemConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getSystemConfig</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Someone makes a mistake in a PR</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> version</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> `version::</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-constant)\">systemConfig</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">SERVICE_API_KEY</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">ClientDashboard</span><span style=\"color:var(--shiki-token-function)\"> version</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{version} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>A better approach is to remove <code>SERVICE_API_KEY</code> from the data returned by <code>getSystemConfig</code>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/trailingSlash",
    "title": "next.config.js: trailingSlash | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">trailingSlash</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>By default Next.js will redirect URLs with trailing slashes to their counterpart without a trailing slash. For example <code>/about/</code> will redirect to <code>/about</code>. You can configure this behavior to act the opposite way, where URLs without trailing slashes are redirected to their counterparts with trailing slashes.</p>\n<p>Open <code>next.config.js</code> and add the <code>trailingSlash</code> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  trailingSlash</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>With this option set, URLs like <code>/about</code> will redirect to <code>/about/</code>.</p>\n<p>When using <code>trailingSlash: true</code>, certain URLs are exceptions and will not have a trailing slash appended:</p>\n<ul>\n<li>Static file URLs, such as files with extensions.</li>\n<li>Any paths under <code>.well-known/</code>.</li>\n</ul>\n<p>For example, the following URLs will remain unchanged: <code>/file.txt</code>, <code>images/photos/picture.png</code>, and <code>.well-known/subfolder/config.json</code>.</p>\n<p>When used with <a href=\"/docs/app/guides/static-exports\"><code>output: \"export\"</code></a> configuration, the <code>/about</code> page will output <code>/about/index.html</code> (instead of the default <code>/about.html</code>).</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v9.5.0</code></td><td><code>trailingSlash</code> added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/transpilePackages",
    "title": "next.config.js: transpilePackages | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">transpilePackages</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->May 27, 2026</div>\n<p>Use <code>transpilePackages</code> to compile and bundle a dependency instead of treating it as untouched runtime code. Values are package names, including scoped names like <code>@scope/pkg</code>. Paths and glob patterns are not supported.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  transpilePackages</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'package-name'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '@scope/pkg'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>This replaces the <code>next-transpile-modules</code> package.</p>\n<h2 id=\"when-you-need-it\" data-docs-heading=\"\">When you need it<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#when-you-need-it\"><span></span></a></h2>\n<p>Turbopack transpiles workspace packages (npm, pnpm, or Yarn workspaces) in your monorepo automatically under both routers. Webpack does the same for the App Router. Add a package to <code>transpilePackages</code> when:</p>\n<ul>\n<li><strong>A <code>node_modules</code> dependency ships raw TypeScript or JSX.</strong> Next.js does not compile code inside <code>node_modules</code> by default. Listing the package opts it in, or you can build the package to plain JavaScript and point its <code>main</code>/<code>exports</code> at the compiled output.</li>\n<li><strong>You build with webpack for the Pages Router and the dependency's source lives outside the next app's directory.</strong> For example, an <code>apps/web</code> app importing <code>packages/ui</code> in the same monorepo.</li>\n<li><strong>You use the Pages Router and want a <code>node_modules</code> dependency bundled into the route.</strong> Pages Router loads <code>node_modules</code> server-side dependencies through Node.js <code>require</code> at runtime. List the package to bundle its source into the route instead. App Router already bundles Server Component and Route Handler dependencies unless the package is listed in <a href=\"/docs/app/api-reference/config/next-config-js/serverExternalPackages\"><code>serverExternalPackages</code></a>.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: A package cannot appear in both <code>transpilePackages</code> and <a href=\"/docs/app/api-reference/config/next-config-js/serverExternalPackages\"><code>serverExternalPackages</code></a>; Next.js throws at build start if it does. Packages listed in <a href=\"/docs/app/api-reference/config/next-config-js/optimizePackageImports\"><code>optimizePackageImports</code></a> and the entries in <a href=\"https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/default-transpiled-packages.json\" rel=\"noopener noreferrer\" target=\"_blank\"><code>default-transpiled-packages.json</code><span class=\"inline-flex not-prose\"></span></a> are added automatically; you do not need to repeat them.</p>\n</blockquote>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v13.0.0</code></td><td><code>transpilePackages</code> added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack",
    "title": "next.config.js: turbopack | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">turbopack</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 7, 2026</div>\n<p>The <code>turbopack</code> option lets you customize <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a> to transform different files and change how modules are resolved.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: The <code>turbopack</code> option was previously named <code>experimental.turbo</code> in Next.js versions 13.0.0 to 15.2.x. The <code>experimental.turbo</code> option will be removed in Next.js 16.</p>\n<p>If you are using an older version of Next.js, run <code>npx @next/codemod@latest next-experimental-turbo-to-turbopack .</code> to automatically migrate your configuration.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // ...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>Turbopack for Next.js does not require loaders or loader configuration for built-in functionality. Turbopack has built-in support for CSS and compiling modern JavaScript, so there's no need for <code>css-loader</code>, <code>postcss-loader</code>, or <code>babel-loader</code> if you're using <code>@babel/preset-env</code>.</li>\n</ul>\n</blockquote>\n<h2 id=\"reference\" data-docs-heading=\"\">Reference<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reference\"><span></span></a></h2>\n<h3 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h3>\n<p>The following options are available for the <code>turbopack</code> configuration:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>root</code></td><td>Sets the application root directory. Should be an absolute path.</td></tr><tr><td><code>rules</code></td><td>List of supported webpack loaders to apply when running with Turbopack.</td></tr><tr><td><code>resolveAlias</code></td><td>Map aliased imports to modules to load in their place.</td></tr><tr><td><code>resolveExtensions</code></td><td>List of extensions to resolve when importing files.</td></tr><tr><td><code>debugIds</code></td><td>Enable generation of <a href=\"https://github.com/tc39/ecma426/blob/main/proposals/debug-id.md\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">debug IDs<span class=\"inline-flex not-prose\"></span></a> in JavaScript bundles and source maps.</td></tr></tbody></table></div>\n<h3 id=\"supported-loaders\" data-docs-heading=\"\">Supported loaders<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#supported-loaders\"><span></span></a></h3>\n<p>The following loaders have been tested to work with Turbopack's webpack loader implementation, but many other webpack loaders should work as well even if not listed here:</p>\n<ul>\n<li><a href=\"https://www.npmjs.com/package/babel-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>babel-loader</code><span class=\"inline-flex not-prose\"></span></a> <a href=\"/docs/app/api-reference/turbopack#language-features\"><em>(Configured automatically if a Babel configuration file is found)</em></a></li>\n<li><a href=\"https://www.npmjs.com/package/@svgr/webpack\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>@svgr/webpack</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/svg-inline-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>svg-inline-loader</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/yaml-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>yaml-loader</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/string-replace-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>string-replace-loader</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/raw-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>raw-loader</code><span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://www.npmjs.com/package/sass-loader\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>sass-loader</code><span class=\"inline-flex not-prose\"></span></a> <a href=\"/docs/app/api-reference/turbopack#css-and-styling\"><em>(Configured automatically)</em></a></li>\n<li><a href=\"https://www.npmjs.com/package/graphql-tag\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>graphql-tag/loader</code><span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<h4 id=\"missing-webpack-loader-features\" data-docs-heading=\"\">Missing Webpack loader features<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#missing-webpack-loader-features\"><span></span></a></h4>\n<p>Turbopack uses the <a href=\"https://github.com/webpack/loader-runner\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>loader-runner</code><span class=\"inline-flex not-prose\"></span></a> library to execute webpack loaders, which provides most of the standard loader API. However, some features are not supported:</p>\n<p><strong>Module loading:</strong></p>\n<ul>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisimportmodule\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>importModule</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisloadmodule\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>loadModule</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n</ul>\n<p><strong>File system and output:</strong></p>\n<ul>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisfs\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>fs</code><span class=\"inline-flex not-prose\"></span></a> - Partial support: only <code>fs.readFile</code> is currently implemented.</li>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisemitfile\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>emitFile</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n</ul>\n<p><strong>Context properties:</strong></p>\n<ul>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisversion\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>version</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n<li><a href=\"https://webpack.js.org/api/loaders/#thismode\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>mode</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n<li><a href=\"https://webpack.js.org/api/loaders/#thistarget\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>target</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n</ul>\n<p><strong>Utilities:</strong></p>\n<ul>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisutils\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>utils</code><span class=\"inline-flex not-prose\"></span></a> - No support</li>\n<li><a href=\"https://webpack.js.org/api/loaders/#thisresolve\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>resolve</code><span class=\"inline-flex not-prose\"></span></a> - No support (use <a href=\"https://webpack.js.org/api/loaders/#thisgetresolve\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>getResolve</code><span class=\"inline-flex not-prose\"></span></a> instead)</li>\n</ul>\n<p>If you have a loader that is critically dependent upon one of these features please file an issue.</p>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"root-directory\" data-docs-heading=\"\">Root directory<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#root-directory\"><span></span></a></h3>\n<p>Turbopack uses the root directory to resolve modules. Files outside of the project root are not resolved.</p>\n<p>The reason files are not resolved outside of the project root is to improve cache validation, reduce filesystem watching overhead, and reduce the number of resolving steps needed.</p>\n<p>Next.js automatically detects the root directory of your project. It does so by looking for one of these files:</p>\n<ul>\n<li><code>pnpm-lock.yaml</code></li>\n<li><code>package-lock.json</code></li>\n<li><code>yarn.lock</code></li>\n<li><code>bun.lock</code></li>\n<li><code>bun.lockb</code></li>\n</ul>\n<p>If you have a different project structure, for example if you don't use workspaces, you can manually set the <code>root</code> option:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> require</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'path'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    root</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> path</span><span style=\"color:var(--shiki-token-function)\">.join</span><span style=\"color:var(--shiki-color-text)\">(__dirname</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '..'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>To resolve files from linked dependencies outside the project root (via <code>npm link</code>, <code>yarn link</code>, <code>pnpm link</code>, etc.), you must configure the <code>turbopack.root</code> to the parent directory of both the project and the linked dependencies.</p>\n<p>While this expands the scope of filesystem watching, it's typically only necessary during development when actively working on linked packages.</p>\n<h3 id=\"configuring-webpack-loaders\" data-docs-heading=\"\">Configuring webpack loaders<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#configuring-webpack-loaders\"><span></span></a></h3>\n<p>If you need loader support beyond what's built in, many webpack loaders already work with Turbopack. There are currently some limitations:</p>\n<ul>\n<li>Only a core subset of the webpack loader API is implemented. Currently, there is enough coverage for some popular loaders, and we'll expand our API support in the future.</li>\n<li>Only loaders that return JavaScript code are supported. Loaders that transform files like stylesheets or images are not currently supported.</li>\n<li>Options passed to webpack loaders must be plain JavaScript primitives, objects, and arrays. For example, it's not possible to pass <code>require()</code> plugin modules as option values.</li>\n</ul>\n<p>To configure loaders, add the names of the loaders you've installed and any options in <code>next.config.js</code>, mapping file extensions to a list of loaders. Rules are evaluated in order.</p>\n<p>Here is an example below using the <a href=\"https://www.npmjs.com/package/@svgr/webpack\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>@svgr/webpack</code><span class=\"inline-flex not-prose\"></span></a> loader, which enables importing <code>.svg</code> files and rendering them as React components.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '*.svg'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        loaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'@svgr/webpack'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        as</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Globs used in the <code>rules</code> object match based on file name, unless the glob contains a <code>/</code> character, which will cause it to match based on the full project-relative file path. Windows file paths are normalized to use unix-style <code>/</code> path separators.</p>\n<p>Turbopack uses a modified version of the <a href=\"https://docs.rs/globset/latest/globset/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Rust <code>globset</code> library<span class=\"inline-flex not-prose\"></span></a>.</p>\n</blockquote>\n<p>For loaders that require configuration options, you can use an object format instead of a string:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '*.svg'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        loaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            loader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '@svgr/webpack'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            options</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">              icon</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        as</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Prior to Next.js version 13.4.4, <code>turbopack.rules</code> was named <code>turbo.loaders</code> and only accepted file extensions like <code>.mdx</code> instead of <code>*.mdx</code>.</p>\n</blockquote>\n<h3 id=\"advanced-webpack-loader-conditions\" data-docs-heading=\"\">Advanced webpack loader conditions<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#advanced-webpack-loader-conditions\"><span></span></a></h3>\n<p>You can further restrict where a loader runs using the advanced <code>condition</code> syntax:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // '*' will match all file paths, but we restrict where our</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // rule runs with a condition.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '*'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        condition</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          all</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // 'foreign' is a built-in condition.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            { not</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'foreign'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // 'path' can be a RegExp or a glob string. A RegExp matches</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">            // anywhere in the full project-relative file path.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /</span><span style=\"color:var(--shiki-token-keyword)\">^</span><span style=\"color:var(--shiki-token-string-expression)\">img\\/[0-9]</span><span style=\"color:var(--shiki-token-keyword)\">{3}</span><span style=\"color:var(--shiki-token-string-expression)\">\\//</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">              any</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">                { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.svg'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">                // 'query' matches anywhere in the full query string,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">                // which can be empty, or start with `?`.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">                { query</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /[?&amp;]svgr(?=&amp;</span><span style=\"color:var(--shiki-token-keyword)\">|$</span><span style=\"color:var(--shiki-token-string-expression)\">)/</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">                // 'content' is always a RegExp, and can match</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">                // anywhere in the file.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">                { content</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /\\&lt;svg\\W/</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">              ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">            }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        loaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'@svgr/webpack'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        as</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<ul>\n<li>Supported boolean operators are <code>{all: [...]}</code>, <code>{any: [...]}</code> and <code>{not: ...}</code>.</li>\n<li>Supported customizable operators are <code>{path: string | RegExp}</code>, <code>{content: RegExp}</code>, <code>{query: string | RegExp}</code>, and <code>{contentType: string | RegExp}</code>. If multiple operators are specified in the same object, it acts as an implicit <code>and</code>.<!-- -->\n<ul>\n<li><code>path</code> matches against the project-relative file path. A string is treated as a glob pattern, while a RegExp can be used to match the path partially.</li>\n<li><code>content</code> matches anywhere in the file content.</li>\n<li><code>query</code> matches the import's query string (e.g., <code>?foo</code> in <code>import './file?foo'</code>). A string must match exactly, while a RegExp can be used to match the query string partially.</li>\n<li><code>contentType</code> matches the MIME content type of the resource (e.g., from data URLs like <code>data:text/plain,...</code>). A string is treated as a glob pattern (e.g., <code>text/*</code>, <code>image/*</code>), while a RegExp can be used to match the content type partially.</li>\n</ul>\n</li>\n</ul>\n<p>In addition, a number of built-in conditions are supported:</p>\n<ul>\n<li><code>browser</code>: Matches code that will execute on the client. Server code can be matched using <code>{not: 'browser'}</code>.</li>\n<li><code>foreign</code>: Matches code in <code>node_modules</code>, as well as some Next.js internals. Usually you'll want to restrict loaders to <code>{not: 'foreign'}</code>. This can improve performance by reducing the number of files the loader is invoked on.</li>\n<li><code>development</code>: Matches when using <code>next dev</code>.</li>\n<li><code>production</code>: Matches when using <code>next build</code>.</li>\n<li><code>node</code>: Matches code that will run on the default Node.js runtime.</li>\n<li><code>edge-light</code>: Matches code that will run on the <a href=\"/docs/app/api-reference/edge\">Edge runtime</a> (deprecated).</li>\n</ul>\n<p>Rules can be an object or an array of objects. An array is often useful for modeling disjoint conditions:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '*.svg'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          condition</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'browser'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          loaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'@svgr/webpack'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          as</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          condition</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { not</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'browser'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          loaders</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-constant)\">require</span><span style=\"color:var(--shiki-token-function)\">.resolve</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./custom-svg-loader.js'</span><span style=\"color:var(--shiki-color-text)\">)]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          as</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: All matching rules are executed in order.</p>\n</blockquote>\n<h3 id=\"module-types\" data-docs-heading=\"\">Module types<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#module-types\"><span></span></a></h3>\n<p>You can set the module type directly without using a loader. This is useful for changing how files are processed, similar to webpack's <a href=\"https://webpack.js.org/configuration/module/#ruletype\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>type</code><span class=\"inline-flex not-prose\"></span></a> option.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    rules</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">      '*.svg'</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'asset'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>When using <code>type: 'asset'</code>, importing the file returns its URL:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> svgUrl </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './icon.svg'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">img</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{svgUrl} </span><span style=\"color:var(--shiki-token-function)\">alt</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"Icon\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The <code>type</code> option can be combined with <code>loaders</code> - loaders run first, then the result is processed according to the specified type.</p>\n<p>Available module types:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>asset</code></td><td>Emit file and return URL (like webpack <code>asset/resource</code>)</td></tr><tr><td><code>ecmascript</code></td><td>Process as JavaScript</td></tr><tr><td><code>typescript</code></td><td>Process as TypeScript</td></tr><tr><td><code>css</code></td><td>Process as CSS</td></tr><tr><td><code>css-module</code></td><td>Process as CSS module</td></tr><tr><td><code>json</code></td><td>Parse as JSON and export it</td></tr><tr><td><code>wasm</code></td><td>Process as WebAssembly</td></tr><tr><td><code>node</code></td><td>Process as a native Node.js addon</td></tr><tr><td><code>raw</code></td><td>Export the contents as a string (an alias of <code>text</code>)</td></tr><tr><td><code>text</code></td><td>Export the contents as a string</td></tr><tr><td><code>bytes</code></td><td>Export the contents as a <code>Uint8Array</code></td></tr></tbody></table></div>\n<h3 id=\"inline-loader-configuration-with-import-attributes\" data-docs-heading=\"\">Inline loader configuration with import attributes<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#inline-loader-configuration-with-import-attributes\"><span></span></a></h3>\n<p>You can apply a Turbopack loader to an individual import using the <code>with</code> clause (import attributes). This is specified per-import rather than globally via <code>turbopack.rules</code>.</p>\n<p>This is useful when you want to apply a loader to a specific import without affecting all files of that type.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Apply a raw loader to import a .txt file as a JavaScript module</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> rawText </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../data.txt'</span><span style=\"color:var(--shiki-token-keyword)\"> with</span><span style=\"color:var(--shiki-color-text)\"> { turbopackLoader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'raw-loader'</span><span style=\"color:var(--shiki-color-text)\">, turbopackAs</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '*.js'</span><span style=\"color:var(--shiki-color-text)\"> }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;{rawText}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The following import attributes are supported:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Attribute</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>turbopackLoader</code></td><td>The loader to apply (e.g. <code>'raw-loader'</code>).</td></tr><tr><td><code>turbopackLoaderOptions</code></td><td>JSON string of loader options (e.g. <code>'{\"search\":\"X\",\"replace\":\"Y\"}'</code>).</td></tr><tr><td><code>turbopackAs</code></td><td>Rename pattern for the output (same as <code>turbopack.rules[].as</code>). For example, <code>'*.js'</code> treats the loader output as JavaScript.</td></tr><tr><td><code>turbopackModuleType</code></td><td>Set the module type for the output (same as <code>turbopack.rules[].type</code>).</td></tr></tbody></table></div>\n<p>Loaders with options pass a JSON-encoded string via <code>turbopackLoaderOptions</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> value </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> '../data.js'</span><span style=\"color:var(--shiki-token-keyword)\"> with</span><span style=\"color:var(--shiki-color-text)\"> { turbopackLoader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'string-replace-loader'</span><span style=\"color:var(--shiki-color-text)\">, turbopackLoaderOptions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '{\"search\":\"PLACEHOLDER\",\"replace\":\"replaced value\"}'</span><span style=\"color:var(--shiki-color-text)\"> }</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Import attributes with <code>turbopackLoader</code> are Turbopack-specific and are not supported by webpack. This feature requires the <code>with</code> keyword (not <code>assert</code>) in your import statements.</p>\n</blockquote>\n<h3 id=\"resolving-aliases\" data-docs-heading=\"\">Resolving aliases<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#resolving-aliases\"><span></span></a></h3>\n<p>Turbopack can be configured to modify module resolution through aliases, similar to webpack's <a href=\"https://webpack.js.org/configuration/resolve/#resolvealias\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>resolve.alias</code><span class=\"inline-flex not-prose\"></span></a> configuration.</p>\n<p>To configure resolve aliases, map imported patterns to their new destination in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    resolveAlias</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      underscore</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'lodash'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      mocha</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { browser</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'mocha/browser-entry.js'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This aliases imports of the <code>underscore</code> package to the <code>lodash</code> package. In other words, <code>import underscore from 'underscore'</code> will load the <code>lodash</code> module instead of <code>underscore</code>.</p>\n<p>Turbopack also supports conditional aliasing through this field, similar to Node.js' <a href=\"https://nodejs.org/docs/latest-v18.x/api/packages.html#conditional-exports\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">conditional exports<span class=\"inline-flex not-prose\"></span></a>. At the moment only the <code>browser</code> condition is supported. In the case above, imports of the <code>mocha</code> module will be aliased to <code>mocha/browser-entry.js</code> when Turbopack targets browser environments.</p>\n<h3 id=\"resolving-custom-extensions\" data-docs-heading=\"\">Resolving custom extensions<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#resolving-custom-extensions\"><span></span></a></h3>\n<p>Turbopack can be configured to resolve modules with custom extensions, similar to webpack's <a href=\"https://webpack.js.org/configuration/resolve/#resolveextensions\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>resolve.extensions</code><span class=\"inline-flex not-prose\"></span></a> configuration.</p>\n<p>To configure resolve extensions, use the <code>resolveExtensions</code> field in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    resolveExtensions</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'.mdx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.tsx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.ts'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.jsx'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.js'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.mjs'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> '.json'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This overwrites the original resolve extensions with the provided list. Make sure to include the default extensions.</p>\n<p>For more information and guidance for how to migrate your app to Turbopack from webpack, see <a href=\"https://turbo.build/pack/docs/migrating-from-webpack\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Turbopack's documentation on webpack compatibility<span class=\"inline-flex not-prose\"></span></a>.</p>\n<h3 id=\"debug-ids\" data-docs-heading=\"\">Debug IDs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#debug-ids\"><span></span></a></h3>\n<p>Turbopack can be configured to generate <a href=\"https://github.com/tc39/ecma426/blob/main/proposals/debug-id.md\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">debug IDs<span class=\"inline-flex not-prose\"></span></a> in JavaScript bundles and source maps.</p>\n<p>To configure debug IDs, use the <code>debugIds</code> field in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    debugIds</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The option automatically adds a polyfill for debug IDs to the JavaScript bundle to ensure compatibility. The debug IDs are available in the <code>globalThis._debugIds</code> global variable.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>16.2.0</code></td><td><code>turbopackLoader</code> import attributes were added.</td></tr><tr><td><code>16.2.0</code></td><td><code>turbopack.rules.*.type</code> was added.</td></tr><tr><td><code>16.2.0</code></td><td><code>turbopack.rules.*.condition.contentType</code> was added.</td></tr><tr><td><code>16.2.0</code></td><td><code>turbopack.rules.*.condition.query</code> was added.</td></tr><tr><td><code>16.0.0</code></td><td><code>turbopack.debugIds</code> was added.</td></tr><tr><td><code>16.0.0</code></td><td><code>turbopack.rules.*.condition</code> was added.</td></tr><tr><td><code>15.3.0</code></td><td><code>experimental.turbo</code> is changed to <code>turbopack</code>.</td></tr><tr><td><code>13.0.0</code></td><td><code>experimental.turbo</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackChunking",
    "title": "next.config.js: turbopackChunking | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">turbopackChunking<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 7, 2026</div>\n<p><code>experimental.turbopackChunking</code> lets you configure Turbopack's production JavaScript\nchunker. These options allow you to change the assumptions the chunker makes about user\nbehaviour, tweak the raw size thresholds it uses, and enable the experimental component\nchunks feature.</p>\n<!-- -->\n<p>By default, Turbopack's chunking is configured as follows:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackChunking</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      minChunkSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 50000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      maxChunkCountPerGroup</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 40</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      maxMergeChunkSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 200000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      minComponentChunkSize</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 20000</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      generateComponentChunks</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">} </span><span style=\"color:var(--shiki-token-keyword)\">satisfies</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"size-thresholds\" data-docs-heading=\"\">Size Thresholds<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#size-thresholds\"><span></span></a></h2>\n<p>The following options control how aggressively Turbopack merges chunks and how large a chunk is\nallowed to grow. Sizes are in bytes of uncompressed, unminified code (roughly 5x\nthe size of the compressed, minified output).</p>\n<ul>\n<li><strong><code>minChunkSize</code></strong> (default <code>50000</code>): Turbopack will avoid creating more\nthan one chunk smaller than this size by merging small chunks into larger ones.\nRaising this number will produce fewer, larger chunks. Meanwhile, lowering it\nwill produce more chunks that are smaller.</li>\n<li><strong><code>maxChunkCountPerGroup</code></strong> (default <code>40</code>): Turbopack will not emit more than\nthis many chunks per chunk group (eg. a route or a dynamic import). Lowering\nthis number will lead to more aggressive merging and less network requests\nper-page. Raising it will produce smaller chunks and increase the likelihood\nof cache hits when navigating.</li>\n<li><strong><code>maxMergeChunkSize</code></strong> (default <code>200000</code>): Turbopack never merges a chunk\nlarger than this size with other chunks. This keeps the code in large chunks\nfrom being duplicated across multiple large output chunks.</li>\n</ul>\n<p>When merging chunks, the trade-off being made is an improvement to performance on initial page\nloads at the cost of navigation performance. This is because each additional network request\nbeing made is costly, however, smaller chunks are more likely to be re-usable across pages.</p>\n<h2 id=\"component-chunks\" data-docs-heading=\"\">Component Chunks<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#component-chunks\"><span></span></a></h2><p>Producing component chunks is an experimental feature that aims to give you the initial\npage load benefits of merged chunks without sacrificing reusability. This feature lets\nthe runtime dynamically choose whether to load a merged chunk as a single file, or to\nload only the component chunks it doesn't already have. Additionally, chunks that were\nalready loaded as part of a merged chunk will not be re-downloaded.</p><p>This avoids re-downloading JavaScript the browser already has when navigating.</p><ul>\n<li><strong><code>generateComponentChunks</code></strong> (default <code>false</code>): when enabled, each merged\nproduction chunk also emits its constituent component chunks alongside it, so\nthe browser runtime can fetch individual component chunks.</li>\n<li><strong><code>minComponentChunkSize</code></strong> (default <code>20000</code>): component chunks smaller than\nthis size are folded into a single component instead of being emitted on their own,\nto avoid producing many tiny chunks.</li>\n</ul>\n<h2 id=\"heuristics\" data-docs-heading=\"\">Heuristics<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#heuristics\"><span></span></a></h2>\n<p>These change the assumptions the chunker makes when weighing whether merging two\nchunks is worth it.</p>\n<ul>\n<li><strong><code>firstPageLoadPriority</code></strong> (a number between <code>0</code> and <code>1</code>): how heavily to\nweight the benefit of merging chunks for a single page load. Higher values\nmerge more eagerly. If you don't have a better value, your site's bounce rate\nis a good approximation.</li>\n<li><strong><code>priorityRoutes</code></strong> (an array of <code>RegExp</code>): routes that are often the first\npage a visitor lands on (e.g. the homepage). Their client-side bundles are\nmerged more eagerly to reduce the single-route request cost, at the cost of\nextra requests when navigating to other pages.</li>\n<li><strong><code>priorityBoost</code></strong> (default <code>1.5</code>): a multiplier on the single-request\nprobability of <code>priorityRoutes</code> routes. Higher values merge those routes'\nbundles more aggressively.</li>\n<li><strong><code>requestCost</code></strong> (default <code>200000</code>): the estimated cost of an\nadditional request, in bytes of uncompressed, unminified code. Larger values\nbias toward fewer, larger chunks and fewer requests overall.</li>\n</ul></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache",
    "title": "next.config.js: turbopackFileSystemCache | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Turbopack FileSystem Caching</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 3, 2026</div><h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>Turbopack FileSystem Cache enables Turbopack to reduce work across <code>next dev</code> or <code>next build</code> commands. When enabled, Turbopack will save and restore data under the <code>.next</code> directory between runs, which can greatly speed up subsequent builds and dev sessions.</p>\n<p>Two options control the cache, one for <code>next dev</code> and one for <code>next build</code>. Both are enabled by default:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackFileSystemCacheForDev</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackFileSystemCacheForBuild</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<ul>\n<li><strong><code>turbopackFileSystemCacheForDev</code></strong> (default: <code>true</code>): caches Turbopack's work for <code>next dev</code> in <code>.next/dev/cache/turbopack</code>. Restarting the dev server reuses the previous compilation.</li>\n<li><strong><code>turbopackFileSystemCacheForBuild</code></strong> (default: <code>true</code>): caches Turbopack's work for <code>next build</code> in <code>.next/cache/turbopack</code>. Subsequent builds start warm. See <a href=\"#build-environments\">Build environments</a>.</li>\n</ul>\n<p>Set either option to <code>false</code> to opt out.</p>\n<h2 id=\"build-environments\" data-docs-heading=\"\">Build environments<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#build-environments\"><span></span></a></h2>\n<p>The build cache lives in <code>.next/cache</code>. Builds only get faster when that directory is restored before each build.</p>\n<ul>\n<li><strong>Self-hosted builds</strong>: reuse the same working directory between builds. Containerized builds start from a clean layer and do not carry <code>.next/cache</code> over unless you cache or mount it explicitly.</li>\n<li><strong>CI providers</strong>: <a href=\"/docs/app/guides/ci-build-caching\">configure build caching</a> for <code>.next/cache</code>.</li>\n</ul>\n<p>If your build environment never preserves <code>.next/cache</code>, set <code>turbopackFileSystemCacheForBuild: false</code> to skip writing a cache that will not be read.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td>FileSystem caching is enabled by default for builds</td></tr><tr><td><code>v16.1.0</code></td><td>FileSystem caching is enabled by default for development</td></tr><tr><td><code>v16.0.0</code></td><td>Beta release with separate flags for build and dev</td></tr><tr><td><code>v15.5.0</code></td><td>Persistent caching released as experimental on canary releases</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackIgnoreIssue",
    "title": "next.config.js: turbopack.ignoreIssue | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">turbopack.ignoreIssue</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->February 13, 2026</div><p>The <code>turbopack.ignoreIssue</code> option allows you to filter out specific <a href=\"/docs/app/api-reference/turbopack\">Turbopack</a> errors and warnings so they do not appear in the CLI output or the error overlay. This is useful for suppressing known warnings that do not affect your application, such as intentionally unresolved optional dependencies.</p>\n<p>This option is only available when using Turbopack (<code>next dev --turbopack</code>).</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/vendor/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<p>Each rule in the <code>ignoreIssue</code> array is an object with the following fields:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Field</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Required</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><a href=\"#path\"><code>path</code></a></td><td><code>string | RegExp</code></td><td>Yes</td><td>Matches against the file path of the issue</td></tr><tr><td><a href=\"#title\"><code>title</code></a></td><td><code>string | RegExp</code></td><td>No</td><td>Matches against the issue title</td></tr><tr><td><a href=\"#description\"><code>description</code></a></td><td><code>string | RegExp</code></td><td>No</td><td>Matches against the issue description</td></tr></tbody></table></div>\n<p>An issue is suppressed when it matches the <code>path</code> <strong>and</strong> all other specified fields in a rule. If only <code>path</code> is provided, any issue from a matching file is suppressed.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> Issue titles and descriptions may change between Turbopack versions. The <code>path</code> field is generally stable, but is not guaranteed to remain consistent for all issue types. When possible, prefer using more specific <code>path</code> patterns over <code>title</code> or <code>description</code> matching.</p>\n</blockquote>\n<h3 id=\"path\" data-docs-heading=\"\"><code>path</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#path\"><span></span></a></h3>\n<p>A <strong>glob pattern</strong> (when a string) or <strong>regular expression</strong> that matches against the file path where the issue originated.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Glob pattern: suppress issues from any file under vendor/</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/vendor/**'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // RegExp: suppress issues from files matching a pattern</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /node_modules\\/legacy-lib/</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"title\" data-docs-heading=\"\"><code>title</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#title\"><span></span></a></h3>\n<p>An <strong>exact string match</strong> (when a string) or <strong>regular expression</strong> that matches against the issue title.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/src/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Module not found'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"description\" data-docs-heading=\"\"><code>description</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#description\"><span></span></a></h3>\n<p>An <strong>exact string match</strong> (when a string) or <strong>regular expression</strong> that matches against the issue description.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/src/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        description</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /Cannot find module 'optional-dep'/</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"suppressing-warnings-for-optional-dependencies\" data-docs-heading=\"\">Suppressing warnings for optional dependencies<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#suppressing-warnings-for-optional-dependencies\"><span></span></a></h3>\n<p>If your code uses <code>try/catch</code> around an optional <code>require()</code> call, Turbopack may report a \"Module not found\" warning. You can suppress it:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/lib/optional-feature/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Module not found'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"combining-multiple-rules\" data-docs-heading=\"\">Combining multiple rules<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#combining-multiple-rules\"><span></span></a></h3>\n<p>You can specify multiple rules to suppress different issues:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  turbopack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreIssue</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/vendor/**'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '**/legacy/**'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> title</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Module not found'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      { path</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /generated\\//</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> description</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /expected identifier/</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.2.0</code></td><td><code>turbopack.ignoreIssue</code> introduced.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"next-steps\" data-docs-heading=\"\">Next Steps</h2><div class=\"mt-2 text-gray-900\">Learn more about Turbopack configuration.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/turbopack\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">turbopack</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure Next.js with Turbopack-specific options</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/turbopack\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">Turbopack</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Turbopack is an incremental bundler optimized for JavaScript and TypeScript, written in Rust, and built into Next.js.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackLocalPostcssConfig",
    "title": "next.config.js: turbopackLocalPostcssConfig | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">turbopackLocalPostcssConfig</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->April 11, 2026</div><p>The <code>turbopackLocalPostcssConfig</code> option changes how Turbopack resolves <code>postcss.config.js</code> files. When enabled, Turbopack searches for the config starting from the CSS file's own directory first, then falls back to the project root. By default, Turbopack checks the project root first, meaning a root-level <code>postcss.config.js</code> always takes precedence over configs in subdirectories.</p>\n<p>This option is only relevant when using Turbopack (<code>next dev</code> or <code>next build</code>).</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackLocalPostcssConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"behavior\" data-docs-heading=\"\">Behavior<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#behavior\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Setting</th><th class=\"min-w-[12ch]\">Config resolution order</th></tr></thead><tbody><tr><td><code>false</code> (default)</td><td>Project root → CSS file's directory</td></tr><tr><td><code>true</code></td><td>CSS file's directory → project root</td></tr></tbody></table></div>\n<p>With the default behavior, a <code>postcss.config.js</code> at the project root is used for all CSS files, and per-directory configs are only applied if no root config exists. Enabling <code>turbopackLocalPostcssConfig</code> reverses this: per-directory configs take precedence, and the root config serves as the fallback.</p>\n<h2 id=\"example\" data-docs-heading=\"\">Example<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#example\"><span></span></a></h2>\n<p>This is useful for projects that need different PostCSS transforms in different directories, such as a monorepo with multiple apps or design system packages:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span>my-app/</span></span>\n<span class=\"line\" data-line=\"\"><span>├── postcss.config.js          ← fallback (applied if no local config is found)</span></span>\n<span class=\"line\" data-line=\"\"><span>├── app/</span></span>\n<span class=\"line\" data-line=\"\"><span>│   └── page.module.css        ← uses root config</span></span>\n<span class=\"line\" data-line=\"\"><span>└── packages/</span></span>\n<span class=\"line\" data-line=\"\"><span>    └── ui/</span></span>\n<span class=\"line\" data-line=\"\"><span>        ├── postcss.config.js  ← takes precedence for files in this directory</span></span>\n<span class=\"line\" data-line=\"\"><span>        └── button.module.css  ← uses packages/ui/postcss.config.js</span></span></code></pre></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td><code>turbopackLocalPostcssConfig</code> introduced.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackMemoryEviction",
    "title": "next.config.js: turbopackMemoryEviction | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Turbopack Memory Eviction</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 7, 2026</div><h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p><code>turbopackMemoryEviction</code> controls whether Turbopack reclaims memory while the persistent (FileSystem) cache is enabled. After Turbopack writes a snapshot of its cache to disk, it can 'evict' the in-memory copies of that data and reload them from disk on demand.</p>\n<p>Currently there are three options</p>\n<ul>\n<li><code>false</code>: never evict. Cached data stays in memory for the lifetime of the process.</li>\n<li><code>'auto'</code> (default): evict after a snapshot only once enough memory has been allocated since the last eviction to make it worthwhile. Leverages thresholds and memory pressure feedback from the operating system.</li>\n<li><code>'full'</code>: evict all possible data from memory every time we save to disk.</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> This option only has an effect in <code>next dev</code> sessions when the <a href=\"/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache\">FileSystem Cache</a> is enabled, since eviction relies on data already being persisted to disk. It is experimental and under active development.</p>\n</blockquote>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackMemoryEviction</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'auto'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"version-changes\" data-docs-heading=\"\">Version Changes<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-changes\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td><code>turbopackMemoryEviction</code> released as experimental.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackRustReactCompiler",
    "title": "next.config.js: turbopackRustReactCompiler | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">turbopackRustReactCompiler<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 29, 2026</div><p>The <code>experimental.turbopackRustReactCompiler</code> option enables the native Rust version of the <a href=\"/docs/app/api-reference/config/next-config-js/reactCompiler\">React Compiler</a>, running it directly inside Turbopack as native code instead of through Node.js as it does with the standard Babel version. This typically results in a noticeable performance improvement.</p>\n<p>This option is released as experimental to gather feedback before it becomes the default.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Enable the React Compiler</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  reactCompiler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Use the Rust port instead of the Babel transform</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    turbopackRustReactCompiler</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"good-to-know\" data-docs-heading=\"\">Good to know<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#good-to-know\"><span></span></a></h2>\n<blockquote class=\"p-3 text-sm\">\n<ul>\n<li>This option requires <a href=\"/docs/app/api-reference/config/next-config-js/reactCompiler\"><code>reactCompiler</code></a> to be enabled. It selects which implementation runs, but does not turn the compiler on by itself.</li>\n<li>This option is only supported with Turbopack. Using it with webpack will throw an error.</li>\n<li>When enabled, you do not need to install <code>babel-plugin-react-compiler</code>. The Rust compiler runs natively inside Turbopack.</li>\n</ul>\n</blockquote>\n<p>See the <a href=\"/docs/app/api-reference/config/next-config-js/reactCompiler\"><code>reactCompiler</code> option documentation</a> for details on how to use the compiler.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.3.0</code></td><td>Introduced the experimental <code>turbopackRustReactCompiler</code> option for the native Rust React Compiler.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/typedRoutes",
    "title": "next.config.js: typedRoutes | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">typedRoutes</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 19, 2025</div><blockquote class=\"p-3 text-sm\">\n<p><strong>Note</strong>: This option has been marked as stable, so you should use <code>typedRoutes</code> instead of <code>experimental.typedRoutes</code>.</p>\n</blockquote>\n<p>Support for <a href=\"/docs/app/api-reference/config/typescript#statically-typed-links\">statically typed links</a>. This feature requires using TypeScript in your project.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typedRoutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/typescript",
    "title": "next.config.js: typescript | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">typescript</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 18, 2026</div>\n<p>Configure TypeScript behavior with the <code>typescript</code> option in <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreBuildErrors</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    tsconfigPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsconfig.json'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Default</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>ignoreBuildErrors</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Allow production builds to complete even with TypeScript errors.</td></tr><tr><td><code>tsconfigPath</code></td><td><code>string</code></td><td><code>'tsconfig.json'</code></td><td>Path to a custom <code>tsconfig.json</code> file.</td></tr></tbody></table></div>\n<h2 id=\"ignorebuilderrors\" data-docs-heading=\"\"><code>ignoreBuildErrors</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#ignorebuilderrors\"><span></span></a></h2>\n<p>Next.js fails your <strong>production build</strong> (<code>next build</code>) when TypeScript errors are present in your project.</p>\n<p>If you'd like Next.js to dangerously produce production code even when your application has errors, you can disable the built-in type checking step.</p>\n<p>Note that this completely skips the TypeScript type checking step. It does not run TypeScript and suppress errors, it bypasses the check entirely.</p>\n<p>If disabled, be sure you are running type checks as part of your build or deploy process, otherwise this can be very dangerous.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // !! WARN !!</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Dangerously allow production builds to successfully complete even if</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // your project has type errors.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // !! WARN !!</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreBuildErrors</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"tsconfigpath\" data-docs-heading=\"\"><code>tsconfigPath</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#tsconfigpath\"><span></span></a></h2>\n<p>Use a different TypeScript configuration file for builds or tooling:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    tsconfigPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsconfig.build.json'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>See the <a href=\"/docs/app/api-reference/config/typescript#custom-tsconfig-path\">TypeScript configuration</a> page for more details.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/urlImports",
    "title": "next.config.js: urlImports | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">urlImports<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>URL imports are an experimental feature that allows you to import modules directly from external servers (instead of from the local disk).</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Warning</strong>: Only use domains that you trust to download and execute on your machine. Please exercise discretion, and caution until the feature is flagged as stable.</p>\n</blockquote>\n<p>To opt-in, add the allowed URL prefixes inside <code>next.config.js</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    urlImports</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'https://example.com/assets/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://cdn.skypack.dev'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Then, you can import modules directly from URLs:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { a</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> b</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> c } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/assets/some/module.js'</span></span></code></pre></div>\n<p>URL Imports can be used everywhere normal package imports can be used.</p>\n<h2 id=\"security-model\" data-docs-heading=\"\">Security Model<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#security-model\"><span></span></a></h2>\n<p>This feature is being designed with <strong>security as the top priority</strong>. To start, we added an experimental flag forcing you to explicitly allow the domains you accept URL imports from. We're working to take this further by limiting URL imports to execute in the browser sandbox using the <a href=\"/docs/app/api-reference/edge\">Edge Runtime</a>.</p>\n<h2 id=\"lockfile\" data-docs-heading=\"\">Lockfile<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#lockfile\"><span></span></a></h2>\n<p>When using URL imports, Next.js will create a <code>next.lock</code> directory containing a lockfile and fetched assets.\nThis directory <strong>must be committed to Git</strong>, not ignored by <code>.gitignore</code>.</p>\n<ul>\n<li>When running <code>next dev</code>, Next.js will download and add all newly discovered URL Imports to your lockfile.</li>\n<li>When running <code>next build</code>, Next.js will use only the lockfile to build the application for production.</li>\n</ul>\n<p>Typically, no network requests are needed and any outdated lockfile will cause the build to fail.\nOne exception is resources that respond with <code>Cache-Control: no-cache</code>.\nThese resources will have a <code>no-cache</code> entry in the lockfile and will always be fetched from the network on each build.</p>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"skypack\" data-docs-heading=\"\">Skypack<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#skypack\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> confetti </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://cdn.skypack.dev/canvas-confetti'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useEffect } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  useEffect</span><span style=\"color:var(--shiki-color-text)\">(() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    confetti</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  })</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;Hello&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"static-image-imports\" data-docs-heading=\"\">Static Image Imports<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#static-image-imports\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Image </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/image'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> logo </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://example.com/assets/logo.png'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Image</span><span style=\"color:var(--shiki-token-function)\"> src</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{logo} </span><span style=\"color:var(--shiki-token-function)\">placeholder</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"blur\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">)</span></span></code></pre></div>\n<h3 id=\"urls-in-css\" data-docs-heading=\"\">URLs in CSS<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#urls-in-css\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">.className</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  background</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> url</span><span style=\"color:var(--shiki-token-constant)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'https://example.com/assets/hero.jpg'</span><span style=\"color:var(--shiki-token-constant)\">)</span><span style=\"color:var(--shiki-color-text)\">;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"asset-imports\" data-docs-heading=\"\">Asset Imports<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#asset-imports\"><span></span></a></h3>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> logo</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'https://example.com/assets/file.txt'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-keyword)\"> import</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">meta</span><span style=\"color:var(--shiki-color-text)\">.url)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">console</span><span style=\"color:var(--shiki-token-function)\">.log</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">logo</span><span style=\"color:var(--shiki-color-text)\">.pathname)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// prints \"/_next/static/media/file.a9727b5d.txt\"</span></span></code></pre></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/useLightningcss",
    "title": "next.config.js: useLightningcss | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">useLightningcss<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->March 11, 2026</div><p>Experimental support for using <a href=\"https://lightningcss.dev\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Lightning CSS<span class=\"inline-flex not-prose\"></span></a> with webpack. Lightning CSS is a fast CSS transformer and minifier, written in Rust.</p>\n<p>If this option is not set, Next.js on webpack uses <a href=\"https://postcss.org/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">PostCSS<span class=\"inline-flex not-prose\"></span></a> with <a href=\"https://www.npmjs.com/package/postcss-preset-env\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>postcss-preset-env</code><span class=\"inline-flex not-prose\"></span></a> by default.</p>\n<p>Turbopack uses Lightning CSS by default since Next 14.2. This configuration option has no effect on Turbopack. Turbopack always uses Lightning CSS.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    useLightningcss</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // default, ignored on Turbopack</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"lightningcssfeatures\" data-docs-heading=\"\"><code>lightningCssFeatures</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#lightningcssfeatures\"><span></span></a></h2>\n<p>By default, Lightning CSS decides which CSS features to transpile based on your <a href=\"https://browsersl.ist/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">browserslist<span class=\"inline-flex not-prose\"></span></a> targets. The <code>lightningCssFeatures</code> option lets you override this by forcing specific features to always be transpiled (<code>include</code>) or never be transpiled (<code>exclude</code>), regardless of browser support.</p>\n<p>This applies to both webpack (when <code>useLightningcss</code> is enabled) and Turbopack.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    useLightningcss</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    lightningCssFeatures</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Always transpile these features, even if targets support them</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      include</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'light-dark'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'oklab-colors'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">      // Never transpile these features, even if targets don't support them</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      exclude</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'nesting'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"options\" data-docs-heading=\"\">Options<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#options\"><span></span></a></h3>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Option</th><th class=\"min-w-[12ch]\">Type</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>include</code></td><td><code>string[]</code></td><td>Features to always transpile, regardless of browser targets.</td></tr><tr><td><code>exclude</code></td><td><code>string[]</code></td><td>Features to never transpile, even when browser targets would require them.</td></tr></tbody></table></div>\n<h3 id=\"available-features\" data-docs-heading=\"\">Available features<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#available-features\"><span></span></a></h3>\n<p>Individual features:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Feature name</th><th class=\"min-w-[12ch]\">Description</th></tr></thead><tbody><tr><td><code>nesting</code></td><td><a href=\"https://drafts.csswg.org/css-nesting/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">CSS Nesting<span class=\"inline-flex not-prose\"></span></a></td></tr><tr><td><code>not-selector-list</code></td><td><code>:not</code> with multiple selectors</td></tr><tr><td><code>dir-selector</code></td><td><code>:dir()</code> selector</td></tr><tr><td><code>lang-selector-list</code></td><td><code>:lang()</code> with multiple languages</td></tr><tr><td><code>is-selector</code></td><td><code>:is()</code> selector</td></tr><tr><td><code>text-decoration-thickness-percent</code></td><td>Percentage values in <code>text-decoration-thickness</code></td></tr><tr><td><code>media-interval-syntax</code></td><td>Media query range interval syntax</td></tr><tr><td><code>media-range-syntax</code></td><td>Media query range syntax (<code>width &gt;= 600px</code>)</td></tr><tr><td><code>custom-media-queries</code></td><td><code>@custom-media</code> rules</td></tr><tr><td><code>clamp-function</code></td><td><code>clamp()</code> function</td></tr><tr><td><code>color-function</code></td><td><code>color()</code> function</td></tr><tr><td><code>oklab-colors</code></td><td><code>oklab()</code> and <code>oklch()</code> colors</td></tr><tr><td><code>lab-colors</code></td><td><code>lab()</code> and <code>lch()</code> colors</td></tr><tr><td><code>p3-colors</code></td><td>Display P3 colors</td></tr><tr><td><code>hex-alpha-colors</code></td><td>4 and 8 digit hex colors with alpha</td></tr><tr><td><code>space-separated-color-notation</code></td><td>Space-separated color notation (<code>rgb(0 0 0)</code>)</td></tr><tr><td><code>font-family-system-ui</code></td><td><code>system-ui</code> font family</td></tr><tr><td><code>double-position-gradients</code></td><td>Double-position gradient stops</td></tr><tr><td><code>vendor-prefixes</code></td><td>Vendor-prefixed properties and values</td></tr><tr><td><code>logical-properties</code></td><td>Logical properties and values</td></tr><tr><td><code>light-dark</code></td><td><code>light-dark()</code> color function</td></tr></tbody></table></div>\n<p>Composite groups (shorthand for enabling multiple features at once):</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Group name</th><th class=\"min-w-[12ch]\">Includes</th></tr></thead><tbody><tr><td><code>selectors</code></td><td><code>nesting</code>, <code>not-selector-list</code>, <code>dir-selector</code>, <code>lang-selector-list</code>, <code>is-selector</code></td></tr><tr><td><code>media-queries</code></td><td><code>media-interval-syntax</code>, <code>media-range-syntax</code>, <code>custom-media-queries</code></td></tr><tr><td><code>colors</code></td><td><code>color-function</code>, <code>oklab-colors</code>, <code>lab-colors</code>, <code>p3-colors</code>, <code>hex-alpha-colors</code>, <code>space-separated-color-notation</code>, <code>light-dark</code></td></tr></tbody></table></div>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>16.2.0</code></td><td><code>lightningCssFeatures</code> added.</td></tr><tr><td><code>15.1.0</code></td><td>Support for <code>useSwcCss</code> was removed from Turbopack.</td></tr><tr><td><code>14.2.0</code></td><td>Turbopack's default CSS processor was changed from <code>@swc/css</code> to Lightning CSS. <code>useLightningcss</code> became ignored on Turbopack, and a legacy <code>experimental.turbo.useSwcCss</code> option was added.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/useOffline",
    "title": "next.config.js: useOffline | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">useOffline<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 28, 2026</div><p>The <code>useOffline</code> configuration option enables offline connectivity detection and automatic retry of failed navigation, prefetch, and Server Action requests. When enabled, it also exposes the <a href=\"/docs/app/api-reference/functions/use-offline\"><code>useOffline</code></a> hook for reading the current offline state from Client Components.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    useOffline</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>When enabled, Next.js will:</p>\n<ul>\n<li>Listen for the browser's <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>offline</code><span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>online</code><span class=\"inline-flex not-prose\"></span></a> events to track connectivity.</li>\n<li>Detect network failures on navigation, prefetch, and Server Action requests.</li>\n<li>Poll for connectivity using <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/HEAD\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>HEAD</code><span class=\"inline-flex not-prose\"></span></a> requests with backoff while offline.</li>\n<li>Automatically retry blocked requests once connectivity is restored.</li>\n<li>Make the <a href=\"/docs/app/api-reference/functions/use-offline\"><code>useOffline</code></a> hook available from <code>next/offline</code>.</li>\n</ul>\n<h2 id=\"how-retry-works\" data-docs-heading=\"\">How retry works<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-retry-works\"><span></span></a></h2>\n<p>The offline state is entered through one of two paths:</p>\n<ul>\n<li><strong>Browser event.</strong> Next.js registers a <code>window.addEventListener('offline', ...)</code> listener. When the OS reports the network interface as down, the offline state flips on immediately.</li>\n<li><strong>Failed fetch.</strong> Any navigation, prefetch, or Server Action request whose <code>fetch()</code> rejects with a non-abort, non-timeout error calls into the offline module. This catches the case where the browser still reports <code>navigator.onLine === true</code> but the actual request cannot reach the origin (captive portal, broken DNS, dead upstream).</li>\n</ul>\n<p>Once in the offline state, a polling loop tries to confirm that connectivity has returned.</p>\n<h3 id=\"the-connectivity-check\" data-docs-heading=\"\">The connectivity check<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#the-connectivity-check\"><span></span></a></h3>\n<p>Each check issues a single <code>HEAD</code> request to the current page's URL with the RSC header set, the same endpoint navigations use. The request is aborted after 200 ms.</p>\n<p>Two outcomes count as \"online\":</p>\n<ol>\n<li>The fetch resolves normally.</li>\n<li>The 200 ms timeout aborts the request. A truly offline request fails almost instantly (DNS or TCP error), so if it's still pending at 200 ms the TCP handshake succeeded and the server is reachable.</li>\n</ol>\n<p>Any other rejection schedules the next check. A successful framework fetch (navigation, prefetch, Server Action) during the offline period also flips the state back to online.</p>\n<h3 id=\"backoff\" data-docs-heading=\"\">Backoff<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#backoff\"><span></span></a></h3>\n<p>Delays between checks are stepped, not exponential, and capped at 3 seconds:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Attempt</th><th class=\"min-w-[12ch]\">Delay before next check</th></tr></thead><tbody><tr><td>1</td><td>500 ms</td></tr><tr><td>2</td><td>1 s</td></tr><tr><td>3</td><td>2 s</td></tr><tr><td>4 and after</td><td>3 s</td></tr></tbody></table></div>\n<p>The browser's <code>online</code> event short-circuits the current wait and runs a connectivity check immediately. Reconnection is detected without waiting for the next scheduled tick.</p>\n<h3 id=\"giving-up\" data-docs-heading=\"\">Giving up<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#giving-up\"><span></span></a></h3>\n<p>The polling loop never gives up on its own. It continues at the 3-second cap until a check succeeds or the page unloads. A device that goes offline for hours and then regains connectivity will have its polling loop resume and resolve normally.</p>\n<h3 id=\"retry-of-framework-requests\" data-docs-heading=\"\">Retry of framework requests<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#retry-of-framework-requests\"><span></span></a></h3>\n<p>While the offline state is active, any navigation, prefetch, or Server Action waits for the next connectivity check to succeed, whether it was newly issued or already in flight when the connection dropped. When the check succeeds, the request runs once; no extra backoff applies.</p>\n<p>If it fails with a network error, the app re-enters the offline state and the polling loop starts again.</p>\n<h3 id=\"traffic-at-reconnection\" data-docs-heading=\"\">Traffic at reconnection<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#traffic-at-reconnection\"><span></span></a></h3>\n<p>A single client does not produce a runaway burst of traffic against its origin:</p>\n<ul>\n<li>While the client is offline, a failed <code>fetch()</code> rejects locally at the browser's network layer. The request never reaches the origin.</li>\n<li>The polling loop issues one <code>HEAD</code> request at a time, with delays capped at 3 seconds. No other framework requests are sent to the origin during the offline period.</li>\n<li>When connectivity returns, each pending navigation and Server Action fires once. Only the last navigation attempt is kept pending, and a typical form button is disabled while its action is pending.</li>\n<li>Prefetches run through the <a href=\"/docs/app/guides/prefetching#prefetch-scheduling\">existing prefetch queue</a>, not all at once.</li>\n</ul>\n<p>In practice, this feature is unlikely to flood your server. The only extra traffic it generates per offline user is the HEAD polling, which stops as soon as connectivity returns. Prefetches, Server Actions, and navigations fire the same number of times they would have without an outage, just delayed.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.x.0</code></td><td><code>experimental.useOffline</code> configuration option introduced.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" data-docs-heading=\"\"></h2><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/use-offline\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">useOffline</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the useOffline hook.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/guides/progressive-web-apps\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">PWAs</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to build a Progressive Web Application (PWA) with Next.js.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/useTypeScriptCli",
    "title": "next.config.js: useTypeScriptCli | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">useTypeScriptCli<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 3, 2026</div><p>By default, <code>next build</code> runs the project-local <code>tsc</code> command instead of loading the TypeScript JavaScript compiler API. This supports TypeScript 6 and enables <a href=\"https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">TypeScript 7<span class=\"inline-flex not-prose\"></span></a> while its JavaScript API is unavailable.</p>\n<p>Install TypeScript 7 in your project:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_54motbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_54motbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_94motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_94motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_d4motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_d4motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_h4motbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_h4motbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> typescript@^7</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>The CLI checker is enabled by default. To use the TypeScript JavaScript compiler API instead, set <code>experimental.useTypeScriptCli</code> to <code>false</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    useTypeScriptCli</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>If you opt out while using TypeScript 7, <code>next build</code> exits because the TypeScript JavaScript compiler API is unavailable.</p>\n<h2 id=\"behavior\" data-docs-heading=\"\">Behavior<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#behavior\"><span></span></a></h2>\n<ul>\n<li>Next.js continues to generate <code>next-env.d.ts</code> and route types and to apply its recommended <code>tsconfig</code> settings before running the checker.</li>\n<li>TypeScript diagnostics are printed directly from <code>tsc</code>. Next.js-specific code frames and error rewriting are not applied.</li>\n<li>The complete project selected by the configured <code>tsconfig</code> file is checked, including test files and <code>.next/dev/types</code> when included. The <a href=\"/docs/app/api-reference/cli/next#next-build-options\"><code>--debug-build-paths</code></a> option does not limit this set and produces a warning when combined with the CLI checker.</li>\n<li><a href=\"/docs/app/api-reference/config/typescript#custom-tsconfig-path\"><code>typescript.tsconfigPath</code></a> selects the project passed to <code>tsc</code>.</li>\n<li><a href=\"/docs/app/api-reference/config/typescript#disabling-typescript-errors-in-production\"><code>typescript.ignoreBuildErrors</code></a> skips the type-checking step, including the CLI checker.</li>\n</ul>\n<p>Learn more about <a href=\"/docs/app/api-reference/config/typescript#using-typescript-7\">using TypeScript 7 with Next.js</a>.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/webVitalsAttribution",
    "title": "next.config.js: webVitalsAttribution | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto flex items-center gap-3\">webVitalsAttribution<span class=\"text-gray-600 hidden xl:inline\"></span></h1><div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none text-blue-900 selection:bg-blue-700 dark-theme:selection:text-blue-1000 [&amp;_a:not([data-geist-button])]:text-blue-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14 border-blue-100 bg-blue-200 not-prose mt-2 mb-6\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1\" data-slot=\"note-content\">This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on<!-- --> <a href=\"https://github.com/vercel/next.js/issues\">GitHub</a>.</div></div></div><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div>\n<p>When debugging issues related to Web Vitals, it is often helpful if we can pinpoint the source of the problem.\nFor example, in the case of Cumulative Layout Shift (CLS), we might want to know the first element that shifted when the single largest layout shift occurred.\nOr, in the case of Largest Contentful Paint (LCP), we might want to identify the element corresponding to the LCP for the page.\nIf the LCP element is an image, knowing the URL of the image resource can help us locate the asset we need to optimize.</p>\n<p>Pinpointing the biggest contributor to the Web Vitals score, aka <a href=\"https://github.com/GoogleChrome/web-vitals/blob/4ca38ae64b8d1e899028c692f94d4c56acfc996c/README.md#attribution\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">attribution<span class=\"inline-flex not-prose\"></span></a>,\nallows us to obtain more in-depth information like entries for <a href=\"https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">PerformanceEventTiming<span class=\"inline-flex not-prose\"></span></a>, <a href=\"https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">PerformanceNavigationTiming<span class=\"inline-flex not-prose\"></span></a> and <a href=\"https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">PerformanceResourceTiming<span class=\"inline-flex not-prose\"></span></a>.</p>\n<p>Attribution is disabled by default in Next.js but can be enabled <strong>per metric</strong> by specifying the following in <code>next.config.js</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    webVitalsAttribution</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">'CLS'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-string-expression)\"> 'LCP'</span><span style=\"color:var(--shiki-color-text)\">]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Valid attribution values are all <code>web-vitals</code> metrics specified in the <a href=\"https://github.com/vercel/next.js/blob/442378d21dd56d6e769863eb8c2cb521a463a2e0/packages/next/shared/lib/utils.ts#L43\" rel=\"noopener noreferrer\" target=\"_blank\"><code>NextWebVitalsMetric</code><span class=\"inline-flex not-prose\"></span></a> type.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/next-config-js/webpack",
    "title": "next.config.js: webpack | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Custom Webpack Config</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->October 17, 2025</div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: changes to webpack config are not covered by semver so proceed at your own risk</p>\n</blockquote>\n<p>Before continuing to add custom webpack configuration to your application make sure Next.js doesn't already support your use-case:</p>\n<ul>\n<li><a href=\"/docs/app/getting-started/css\">CSS imports</a></li>\n<li><a href=\"/docs/app/getting-started/css#css-modules\">CSS modules</a></li>\n<li><a href=\"/docs/app/guides/sass\">Sass/SCSS imports</a></li>\n<li><a href=\"/docs/app/guides/sass\">Sass/SCSS modules</a></li>\n</ul>\n<!-- -->\n<p>Some commonly asked for features are available as plugins:</p>\n<ul>\n<li><a href=\"https://github.com/vercel/next.js/tree/canary/packages/next-mdx\" rel=\"noopener noreferrer\" target=\"_blank\">@next/mdx<span class=\"inline-flex not-prose\"></span></a></li>\n<li><a href=\"https://github.com/vercel/next.js/tree/canary/packages/next-bundle-analyzer\" rel=\"noopener noreferrer\" target=\"_blank\">@next/bundle-analyzer<span class=\"inline-flex not-prose\"></span></a></li>\n</ul>\n<p>In order to extend our usage of <code>webpack</code>, you can define a function that extends its config inside <code>next.config.js</code>, like so:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  webpack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    { buildId</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> dev</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> isServer</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> defaultLoaders</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> nextRuntime</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> webpack }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Important: return the modified config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p>The <code>webpack</code> function is executed three times, twice for the server (nodejs / edge runtime) and once for the client. This allows you to distinguish between client and server configuration using the <code>isServer</code> property.</p>\n</blockquote>\n<p>The second argument to the <code>webpack</code> function is an object with the following properties:</p>\n<ul>\n<li><code>buildId</code>: <code>String</code> - The build id, used as a unique identifier between builds.</li>\n<li><code>dev</code>: <code>Boolean</code> - Indicates if the compilation will be done in development.</li>\n<li><code>isServer</code>: <code>Boolean</code> - It's <code>true</code> for server-side compilation, and <code>false</code> for client-side compilation.</li>\n<li><code>nextRuntime</code>: <code>String | undefined</code> - The target runtime for server-side compilation; either <code>\"edge\"</code> or <code>\"nodejs\"</code>, it's <code>undefined</code> for client-side compilation.</li>\n<li><code>defaultLoaders</code>: <code>Object</code> - Default loaders used internally by Next.js:<!-- -->\n<ul>\n<li><code>babel</code>: <code>Object</code> - Default <code>babel-loader</code> configuration.</li>\n</ul>\n</li>\n</ul>\n<p>Example usage of <code>defaultLoaders.babel</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Example config for adding a loader that depends on babel-loader</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// This source was taken from the @next/mdx plugin source:</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// https://github.com/vercel/next.js/tree/canary/packages/next-mdx</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  webpack</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> (config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> options) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">    config</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">rules</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      test</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> /\\.mdx/</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      use</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">        options</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">defaultLoaders</span><span style=\"color:var(--shiki-color-text)\">.babel</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          loader</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '@mdx-js/loader'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          options</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> pluginOptions</span><span style=\"color:var(--shiki-color-text)\">.options</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    })</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> config</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h4 id=\"nextruntime\" data-docs-heading=\"\"><code>nextRuntime</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#nextruntime\"><span></span></a></h4>\n<p>Notice that <code>isServer</code> is <code>true</code> when <code>nextRuntime</code> is <code>\"edge\"</code> or <code>\"nodejs\"</code>, <code>nextRuntime</code> <code>\"edge\"</code> is currently for proxy and Server Components in edge runtime only.</p></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/config/typescript",
    "title": "Configuration: TypeScript | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">TypeScript</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 3, 2026</div>\n<p>Next.js comes with built-in TypeScript, automatically installing the necessary packages and configuring the proper settings when you create a new project with <code>create-next-app</code>.</p>\n<p>To add TypeScript to an existing project, rename a file to <code>.ts</code> / <code>.tsx</code>. Run <code>next dev</code> and <code>next build</code> to automatically install the necessary dependencies and add a <code>tsconfig.json</code> file with the recommended config options.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you already have a <code>jsconfig.json</code> file, copy the <code>paths</code> compiler option from the old <code>jsconfig.json</code> into the new <code>tsconfig.json</code> file, and delete the old <code>jsconfig.json</code> file.</p>\n</blockquote>\n<h2 id=\"using-typescript-7\" data-docs-heading=\"\">Using TypeScript 7<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-typescript-7\"><span></span></a></h2>\n<p><a href=\"https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">TypeScript 7<span class=\"inline-flex not-prose\"></span></a> does not currently provide the JavaScript compiler API. To use TypeScript 7 during <code>next build</code>, install it in your project:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"flex items-center justify-between bg-[var(--ds-background-200)] border-[var(--ds-gray-400)] pt-3 pl-4 overflow-x-auto border-b-0 pb-0\" style=\"scrollbar-width:none;-ms-overflow-style:none\"><div aria-orientation=\"horizontal\" class=\"group no-scrollbar flex flex-nowrap items-center pb-px overflow-x-auto has-[:focus-visible]:overflow-visible gap-2 !shadow-none\" data-geist-tabs=\"\" data-variant=\"secondary\" data-version=\"v1\" role=\"tablist\"><button aria-controls=\"_R_191iotbsnuiubaaivb_\" aria-selected=\"true\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_191iotbsnuiubaaivb_\" role=\"tab\" tabindex=\"0\" type=\"button\" value=\"pnpm\">pnpm</button><button aria-controls=\"_R_291iotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_291iotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"npm\">npm</button><button aria-controls=\"_R_391iotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_391iotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"yarn\">yarn</button><button aria-controls=\"_R_491iotbsnuiubaaivb_\" aria-selected=\"false\" class=\"cursor-pointer outline-0 flex items-center bg-transparent -mb-px py-3.5 px-0.5 text-[var(--ds-gray-900)] border-0 border-b-2 border-transparent text-sm aria-selected:text-[var(--ds-gray-1000)] group-data-[variant=primary]:aria-selected:border-b-2 group-data-[variant=primary]:aria-selected:border-[var(--ds-gray-1000)] focus-visible:data-[show-focus-ring=true]:shadow-[var(--ds-focus-ring)] not-disabled:hover:text-[var(--ds-gray-1000)] disabled:cursor-not-allowed group-data-[variant=secondary]:border-b-0 group-data-[variant=secondary]:h-6 group-data-[variant=secondary]:px-1.5 group-data-[variant=secondary]:py-0 group-data-[variant=secondary]:rounded-md group-data-[variant=secondary]:bg-[var(--ds-gray-alpha-200)] group-data-[variant=secondary]:text-[var(--ds-gray-1000)] group-data-[variant=secondary]:text-[13px] group-data-[variant=secondary]:aria-selected:bg-[var(--ds-gray-1000)] group-data-[variant=secondary]:aria-selected:text-[var(--ds-background-100)] group-data-[variant=secondary]:disabled:bg-[var(--ds-gray-200)] group-data-[variant=secondary]:disabled:text-[var(--ds-gray-900)] group-data-[variant=secondary]:disabled:cursor-not-allowed\" data-geist-tab=\"\" data-show-focus-ring=\"true\" id=\"_R_491iotbsnuiubaaivb_\" role=\"tab\" tabindex=\"-1\" type=\"button\" value=\"bun\">bun</button></div></div><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">pnpm</span><span style=\"color:var(--shiki-token-string)\"> add</span><span style=\"color:var(--shiki-token-string)\"> -D</span><span style=\"color:var(--shiki-token-string)\"> typescript@^7</span></span></code></pre></div>\n<!-- -->\n<!-- -->\n<!-- -->\n<p>Next.js uses the project-local <code>tsc</code> CLI by default, so no additional configuration is required. To use the JavaScript compiler API instead, set <a href=\"/docs/app/api-reference/config/next-config-js/useTypeScriptCli\"><code>experimental.useTypeScriptCli</code></a> to <code>false</code>.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>CLI type checking prints the native <code>tsc</code> diagnostics. It does not apply Next.js-specific code frames or rewrite errors for routes, pages, layouts, or route handlers.</li>\n<li>The CLI checks the complete project selected by your <code>tsconfig</code> file. This includes test files and <code>.next/dev/types</code> when they are included by that configuration. <a href=\"/docs/app/api-reference/cli/next#next-build-options\"><code>next build --debug-build-paths</code></a> does not narrow the files that are type checked and produces a warning when used with this option.</li>\n<li><a href=\"#custom-tsconfig-path\"><code>typescript.tsconfigPath</code></a> continues to select the configuration passed to <code>tsc</code>. <a href=\"#disabling-typescript-errors-in-production\"><code>typescript.ignoreBuildErrors</code></a> skips the type-checking step, including the CLI checker.</li>\n<li><code>experimental.useTypeScriptCli</code> is experimental and its behavior may change.</li>\n</ul>\n</blockquote>\n<h2 id=\"ide-plugin\" data-docs-heading=\"\">IDE Plugin<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#ide-plugin\"><span></span></a></h2><p>Next.js includes a custom TypeScript plugin and type checker, which VSCode and other code editors can use for advanced type-checking and auto-completion.</p><p>You can enable the plugin in VS Code by:</p><ol>\n<li>Opening the command palette (<code>Ctrl/⌘</code> + <code>Shift</code> + <code>P</code>)</li>\n<li>Searching for \"TypeScript: Select TypeScript Version\"</li>\n<li>Selecting \"Use Workspace Version\"</li>\n</ol><figure><img alt=\"TypeScript Command Palette\" loading=\"lazy\" width=\"1600\" height=\"637\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 dark-theme:hidden\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ftypescript-command-palette.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ftypescript-command-palette.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Flight%2Ftypescript-command-palette.png&amp;w=3840&amp;q=75\"><img alt=\"TypeScript Command Palette\" loading=\"lazy\" width=\"1600\" height=\"637\" decoding=\"async\" data-nimg=\"1\" class=\"rounded-md border border-gray-200 bg-gray-100 hidden dark-theme:block\" style=\"color:transparent\" srcset=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ftypescript-command-palette.png&amp;w=1920&amp;q=75 1x, /_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ftypescript-command-palette.png&amp;w=3840&amp;q=75 2x\" src=\"/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fdocs%2Fdark%2Ftypescript-command-palette.png&amp;w=3840&amp;q=75\"></figure><p>Now, when editing files, the custom plugin will be enabled. By default, the project-local <code>tsc</code> CLI is used when running <code>next build</code>. Set <a href=\"#using-typescript-7\"><code>experimental.useTypeScriptCli</code></a> to <code>false</code> to use the custom type checker instead.</p><p>The TypeScript plugin can help with:</p><ul>\n<li>Warning if invalid values for <a href=\"/docs/app/api-reference/file-conventions/route-segment-config\">segment config options</a> are passed.</li>\n<li>Showing available options and in-context documentation.</li>\n<li>Ensuring the <code>'use client'</code> directive is used correctly.</li>\n<li>Ensuring client hooks (like <code>useState</code>) are only used in Client Components.</li>\n</ul><blockquote class=\"p-3 text-sm\">\n<p><strong>🎥 Watch:</strong> Learn about the built-in TypeScript plugin → <a href=\"https://www.youtube.com/watch?v=pqMqn9fKEf8\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">YouTube (3 minutes)<span class=\"inline-flex not-prose\"></span></a></p>\n</blockquote><h2 id=\"end-to-end-type-safety\" data-docs-heading=\"\">End-to-End Type Safety<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#end-to-end-type-safety\"><span></span></a></h2><p>The Next.js App Router has <strong>enhanced type safety</strong>. This includes:</p><ol>\n<li><strong>No serialization of data between fetching function and page</strong>: You can <code>fetch</code> directly in components, layouts, and pages on the server. This data <em>does not</em> need to be serialized (converted to a string) to be passed to the client side for consumption in React. Instead, since <code>app</code> uses Server Components by default, we can use values like <code>Date</code>, <code>Map</code>, <code>Set</code>, and more without any extra steps. Previously, you needed to manually type the boundary between server and client with Next.js-specific types.</li>\n<li><strong>Streamlined data flow between components</strong>: With the removal of <code>_app</code> in favor of root layouts, it is now easier to visualize the data flow between components and pages. Previously, data flowing between individual <code>pages</code> and <code>_app</code> were difficult to type and could introduce confusing bugs. With <a href=\"/docs/app/getting-started/fetching-data\">colocated data fetching</a> in the App Router, this is no longer an issue.</li>\n</ol><p><a href=\"/docs/app/getting-started/fetching-data\">Data Fetching in Next.js</a> now provides as close to end-to-end type safety as possible without being prescriptive about your database or content provider selection.</p><p>We're able to type the response data as you would expect with normal TypeScript. For example:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> res</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'https://api.example.com/...'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // The return value is *not* serialized</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // You can return Date, Map, Set, etc.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> res</span><span style=\"color:var(--shiki-token-function)\">.json</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> name</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-string-expression)\"> '...'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>For <em>complete</em> end-to-end type safety, this also requires your database or content provider to support TypeScript. This could be through using an <a href=\"https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">ORM<span class=\"inline-flex not-prose\"></span></a> or type-safe query builder.</p><h2 id=\"route-aware-type-helpers\" data-docs-heading=\"\">Route-Aware Type Helpers<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#route-aware-type-helpers\"><span></span></a></h2><p>Next.js generates global helpers for App Router route types. These are available without imports and are generated during <code>next dev</code>, <code>next build</code>, or via <a href=\"/docs/app/api-reference/cli/next#next-typegen-options\"><code>next typegen</code></a>:</p><ul>\n<li><a href=\"/docs/app/api-reference/file-conventions/page#page-props-helper\"><code>PageProps</code></a></li>\n<li><a href=\"/docs/app/api-reference/file-conventions/layout#layout-props-helper\"><code>LayoutProps</code></a></li>\n<li><a href=\"/docs/app/api-reference/file-conventions/route#route-context-helper\"><code>RouteContext</code></a></li>\n</ul>\n<h2 id=\"next-envdts\" data-docs-heading=\"\"><code>next-env.d.ts</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#next-envdts\"><span></span></a></h2>\n<p>Next.js generates a <code>next-env.d.ts</code> file in your project root. This file references Next.js type definitions, allowing TypeScript to recognize non-code imports (images, stylesheets, etc.) and Next.js-specific types.</p>\n<p>Running <code>next dev</code>, <code>next build</code>, or <a href=\"/docs/app/api-reference/cli/next#next-typegen-options\"><code>next typegen</code></a> regenerates this file.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li><code>next-env.d.ts</code> is managed by Next.js. Its contents are an implementation detail and may change over time. Add it to <code>.gitignore</code>. If your project already tracks the file, remove it from Git. Do not edit this file manually.</li>\n<li>The file must be in your <code>tsconfig.json</code> <code>include</code> array (<code>create-next-app</code> does this automatically).</li>\n</ul>\n</blockquote>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"type-checking-nextjs-configuration-files\" data-docs-heading=\"\">Type Checking Next.js Configuration Files<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#type-checking-nextjs-configuration-files\"><span></span></a></h3>\n<p>You can use TypeScript and import types in your Next.js configuration by using <code>next.config.ts</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>Module resolution in <code>next.config.ts</code> is currently limited to CommonJS. However, ECMAScript Modules (ESM) syntax is available when <a href=\"#using-nodejs-native-typescript-resolver-for-nextconfigts\">using Node.js native TypeScript resolver</a> for Node.js v22.10.0 and higher.</p>\n<p>When using the <code>next.config.js</code> file, you can add some type checking in your IDE using JSDoc as below:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.js</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// @ts-check</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">/** </span><span style=\"color:var(--shiki-token-keyword)\">@type</span><span style=\"color:var(--shiki-token-function)\"> {import('next').NextConfig}</span><span style=\"color:var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">module</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">exports</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<h3 id=\"using-nodejs-native-typescript-resolver-for-nextconfigts\" data-docs-heading=\"\">Using Node.js Native TypeScript Resolver for <code>next.config.ts</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#using-nodejs-native-typescript-resolver-for-nextconfigts\"><span></span></a></h3>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Note</strong>: Available on Node.js v22.10.0+ and only when the feature is enabled. Next.js does not enable it.</p>\n</blockquote>\n<p>Next.js detects the <a href=\"https://nodejs.org/api/typescript.html\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Node.js native TypeScript resolver<span class=\"inline-flex not-prose\"></span></a> via <a href=\"https://nodejs.org/api/process.html#processfeaturestypescript\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>process.features.typescript</code><span class=\"inline-flex not-prose\"></span></a>, added in <strong>v22.10.0</strong>. When present, <code>next.config.ts</code> can use native ESM, including top‑level <code>await</code> and dynamic <code>import()</code>. This mechanism inherits the capabilities and limitations of Node's resolver.</p>\n<p>In Node.js versions <strong>v22.18.0+</strong>, <code>process.features.typescript</code> is enabled by default. For versions between <strong>v22.10.0</strong> and <strong>22.17.x</strong>, opt in with <code>NODE_OPTIONS=--experimental-transform-types</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] [&amp;_.line]:before:!hidden not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">Terminal</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NODE_OPTIONS</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">--experimental-transform-types</span><span style=\"color:var(--shiki-token-function)\"> next</span><span style=\"color:var(--shiki-token-keyword)\"> &lt;</span><span style=\"color:var(--shiki-token-string)\">comman</span><span style=\"color:var(--shiki-color-text)\">d</span><span style=\"color:var(--shiki-token-keyword)\">&gt;</span></span></code></pre></div>\n<h4 id=\"for-commonjs-projects-default\" data-docs-heading=\"\">For CommonJS Projects (Default)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#for-commonjs-projects-default\"><span></span></a></h4>\n<p>Although <code>next.config.ts</code> supports native ESM syntax in CommonJS projects, Node.js will still assume <code>next.config.ts</code> is a CommonJS file by default, resulting in Node.js reparsing the file as ESM when module syntax is detected. Therefore, we recommend using the <code>next.config.mts</code> file for CommonJS projects to explicitly indicate it's an ESM module:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.mts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Top-level await and dynamic import are supported</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> flags</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-keyword)\"> import</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'./flags.js'</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.then</span><span style=\"color:var(--shiki-color-text)\">((m) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> m</span><span style=\"color:var(--shiki-color-text)\">.default </span><span style=\"color:var(--shiki-token-keyword)\">??</span><span style=\"color:var(--shiki-color-text)\"> m)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  /* config options here */</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typedRoutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Boolean</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-constant)\">flags</span><span style=\"color:var(--shiki-color-text)\">?.typedRoutes)</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<h4 id=\"for-esm-projects\" data-docs-heading=\"\">For ESM Projects<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#for-esm-projects\"><span></span></a></h4>\n<p>When <code>\"type\"</code> is set to <code>\"module\"</code> in <code>package.json</code>, your project uses ESM. Learn more about this setting <a href=\"https://nodejs.org/api/packages.html#type\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">in the Node.js docs<span class=\"inline-flex not-prose\"></span></a>. In this case, you can write <code>next.config.ts</code> directly with ESM syntax.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: When using <code>\"type\": \"module\"</code> in your <code>package.json</code>, all <code>.js</code> and <code>.ts</code> files in your project are treated as ESM modules by default. You may need to rename files with CommonJS syntax to <code>.cjs</code> or <code>.cts</code> extensions if needed.</p>\n</blockquote>\n<h3 id=\"statically-typed-links\" data-docs-heading=\"\">Statically Typed Links<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#statically-typed-links\"><span></span></a></h3>\n<p>Next.js can statically type links to prevent typos and other errors when using <code>next/link</code>, improving type safety when navigating between pages.</p>\n<p>Works in both the Pages and App Router for the <code>href</code> prop in <code>next/link</code>. In the App Router, it also types <code>next/navigation</code> methods like <code>push</code>, <code>replace</code>, and <code>prefetch</code>. It does not type <code>next/router</code> methods in Pages Router.</p>\n<p>Literal <code>href</code> strings are validated, while non-literal <code>href</code>s may require a cast with <code>as Route</code>.</p>\n<p>To opt-into this feature, <code>typedRoutes</code> needs to be enabled and the project needs to be using TypeScript.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typedRoutes</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>Next.js will generate a link definition in <code>.next/types</code> that contains information about all existing routes in your application, which TypeScript can then use to provide feedback in your editor about invalid links.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: If you set up your project without <code>create-next-app</code>, ensure the generated Next.js types are included by adding <code>.next/types/**/*.ts</code> to the <code>include</code> array in your <code>tsconfig.json</code>:</p>\n</blockquote>\n<!-- -->\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">tsconfig.json</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"include\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"next-env.d.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \".next/types/**/*.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"**/*.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"**/*.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"exclude\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">\"node_modules\"</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>Currently, support includes any string literal, including dynamic segments. For non-literal strings, you need to manually cast with <code>as Route</code>. The example below shows both <code>next/link</code> and <code>next/navigation</code> usage:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/example-client.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { Route } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { useRouter } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/navigation'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Example</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> useRouter</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> slug</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-string-expression)\"> 'nextjs'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* Link: literal and dynamic */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/about\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">`/blog/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">slug</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{(</span><span style=\"color:var(--shiki-token-string-expression)\">'/blog/'</span><span style=\"color:var(--shiki-token-keyword)\"> +</span><span style=\"color:var(--shiki-color-text)\"> slug) </span><span style=\"color:var(--shiki-token-keyword)\">as</span><span style=\"color:var(--shiki-token-function)\"> Route</span><span style=\"color:var(--shiki-color-text)\">} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* TypeScript error if href is not a valid route */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"/aboot\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* Router: literal and dynamic strings are validated */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/about'</span><span style=\"color:var(--shiki-color-text)\">)}&gt;Push About&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-function)\">.replace</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`/blog/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">slug</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        Replace Blog</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-function)\">.prefetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/contact'</span><span style=\"color:var(--shiki-color-text)\">)}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        Prefetch Contact</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* For non-literal strings, cast to Route */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> router</span><span style=\"color:var(--shiki-token-function)\">.push</span><span style=\"color:var(--shiki-color-text)\">((</span><span style=\"color:var(--shiki-token-string-expression)\">'/blog/'</span><span style=\"color:var(--shiki-token-keyword)\"> +</span><span style=\"color:var(--shiki-color-text)\"> slug) </span><span style=\"color:var(--shiki-token-keyword)\">as</span><span style=\"color:var(--shiki-token-function)\"> Route</span><span style=\"color:var(--shiki-color-text)\">)}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        Push Non-literal Blog</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>The same applies for redirecting routes defined by proxy:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">proxy.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { NextRequest</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> NextResponse } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> proxy</span><span style=\"color:var(--shiki-color-text)\">(request</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextRequest</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  if</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-constant)\">request</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">nextUrl</span><span style=\"color:var(--shiki-color-text)\">.pathname </span><span style=\"color:var(--shiki-token-keyword)\">===</span><span style=\"color:var(--shiki-token-string-expression)\"> '/proxy-redirect'</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.redirect</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">new</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-constant)\"> request</span><span style=\"color:var(--shiki-color-text)\">.url))</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-constant)\"> NextResponse</span><span style=\"color:var(--shiki-token-function)\">.next</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/some/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { Route } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-string-expression)\">'/proxy-redirect'</span><span style=\"color:var(--shiki-token-keyword)\"> as</span><span style=\"color:var(--shiki-token-function)\"> Route</span><span style=\"color:var(--shiki-color-text)\">}&gt;Link Text&lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>To accept <code>href</code> in a custom component wrapping <code>next/link</code>, use a generic:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { Route } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> Card</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">T</span><span style=\"color:var(--shiki-token-keyword)\"> extends</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">&gt;({ href }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { href</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Route</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">T</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-keyword)\">|</span><span style=\"color:var(--shiki-token-function)\"> URL</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{href}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;My Card&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also type a simple data structure and iterate to render links:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">components/nav-items.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { Route } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">type</span><span style=\"color:var(--shiki-token-function)\"> NavItem</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">T</span><span style=\"color:var(--shiki-token-keyword)\"> extends</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  href</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> T</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  label</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> const</span><span style=\"color:var(--shiki-token-constant)\"> navItems</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NavItem</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-function)\">Route</span><span style=\"color:var(--shiki-color-text)\">&gt;[] </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  { href</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> label</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Home'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  { href</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/about'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> label</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'About'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  { href</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '/blog'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> label</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'Blog'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">]</span></span></code></pre></div>\n<p>Then, map over the items to render <code>Link</code>s:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">components/nav.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> Link </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/link'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { navItems } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './nav-items'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Nav</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-constant)\">navItems</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((item) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-token-function)\"> key</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">item</span><span style=\"color:var(--shiki-color-text)\">.href} </span><span style=\"color:var(--shiki-token-function)\">href</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">item</span><span style=\"color:var(--shiki-color-text)\">.href}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">          {</span><span style=\"color:var(--shiki-token-constant)\">item</span><span style=\"color:var(--shiki-color-text)\">.label}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Link</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ))}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">nav</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>How does it work?</strong></p>\n<p>When running, <code>next typegen</code>, <code>next dev</code> or <code>next build</code>, Next.js generates a hidden <code>.d.ts</code> file inside <code>.next</code> that contains information about all existing routes in your application (all valid routes as the <code>href</code> type of <code>Link</code>). This <code>.d.ts</code> file is included in <code>tsconfig.json</code> and the TypeScript compiler will check that <code>.d.ts</code> and provide feedback in your editor about invalid links.</p>\n</blockquote>\n<h3 id=\"type-intellisense-for-environment-variables\" data-docs-heading=\"\">Type IntelliSense for Environment Variables<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#type-intellisense-for-environment-variables\"><span></span></a></h3>\n<p>During development, Next.js generates a <code>.d.ts</code> file in <code>.next/types</code> that contains information about the loaded environment variables for your editor's IntelliSense. If the same environment variable key is defined in multiple files, it is deduplicated according to the <a href=\"/docs/app/guides/environment-variables#environment-variable-load-order\">Environment Variable Load Order</a>.</p>\n<p>To opt-into this feature, <code>experimental.typedEnv</code> needs to be enabled and the project needs to be using TypeScript.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  experimental</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    typedEnv</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: Types are generated based on the environment variables loaded at development runtime, which excludes variables from <code>.env.production*</code> files by default. To include production-specific variables, run <code>next dev</code> with <code>NODE_ENV=production</code>.</p>\n</blockquote>\n<h3 id=\"with-async-server-components\" data-docs-heading=\"\">With Async Server Components<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#with-async-server-components\"><span></span></a></h3><p>To use an <code>async</code> Server Component with TypeScript, ensure you are using TypeScript <code>5.1.3</code> or higher and <code>@types/react</code> <code>18.2.8</code> or higher.</p><p>If you are using an older version of TypeScript, you may see a <code>'Promise&lt;Element&gt;' is not a valid JSX element</code> type error. Updating to the latest version of TypeScript and <code>@types/react</code> should resolve this issue.</p>\n<!-- -->\n<h3 id=\"incremental-type-checking\" data-docs-heading=\"\">Incremental type checking<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#incremental-type-checking\"><span></span></a></h3>\n<p>Since <code>v10.2.1</code> Next.js supports <a href=\"https://www.typescriptlang.org/tsconfig#incremental\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">incremental type checking<span class=\"inline-flex not-prose\"></span></a> when enabled in your <code>tsconfig.json</code>, this can help speed up type checking in larger applications.</p>\n<h3 id=\"custom-tsconfig-path\" data-docs-heading=\"\">Custom <code>tsconfig</code> path<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#custom-tsconfig-path\"><span></span></a></h3>\n<p>In some cases, you might want to use a different TypeScript configuration for builds or tooling. To do that, set <code>typescript.tsconfigPath</code> in <code>next.config.ts</code> to point Next.js to another <code>tsconfig</code> file.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    tsconfigPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsconfig.build.json'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<p>For example, switch to a different config for production builds:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> isProd</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-constant)\"> process</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">env</span><span style=\"color:var(--shiki-color-text)\">.</span><span style=\"color:var(--shiki-token-constant)\">NODE_ENV</span><span style=\"color:var(--shiki-token-keyword)\"> ===</span><span style=\"color:var(--shiki-token-string-expression)\"> 'production'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    tsconfigPath</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> isProd </span><span style=\"color:var(--shiki-token-keyword)\">?</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsconfig.build.json'</span><span style=\"color:var(--shiki-token-keyword)\"> :</span><span style=\"color:var(--shiki-token-string-expression)\"> 'tsconfig.json'</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<details><summary>Why you might use a separate <code>tsconfig</code> for builds</summary><p>You might need to relax checks in scenarios like monorepos, where the build also validates shared dependencies that don't match your project's standards, or when loosening checks in CI to continue delivering while migrating locally to stricter TypeScript settings (and still wanting your IDE to highlight misuse).</p><p>For example, if your project uses <code>useUnknownInCatchVariables</code> but some monorepo dependencies still assume <code>any</code>:</p><div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">tsconfig.build.json</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"extends\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> \"./tsconfig.json\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"compilerOptions\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    \"useUnknownInCatchVariables\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-constant)\"> false</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div><p>This keeps your editor strict via <code>tsconfig.json</code> while allowing the production build to use relaxed settings.</p></details>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>IDEs typically read <code>tsconfig.json</code> for diagnostics and IntelliSense, so you can still see IDE warnings while production builds use the alternate config. Mirror critical options if you want parity in the editor.</li>\n<li>In development, only <code>tsconfig.json</code> is watched for changes. If you edit a different file name via <code>typescript.tsconfigPath</code>, restart the dev server to apply changes.</li>\n<li>The configured file is used in <code>next dev</code>, <code>next build</code>, and <code>next typegen</code>.</li>\n</ul>\n</blockquote>\n<h3 id=\"disabling-typescript-errors-in-production\" data-docs-heading=\"\">Disabling TypeScript errors in production<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#disabling-typescript-errors-in-production\"><span></span></a></h3>\n<p>Next.js fails your <strong>production build</strong> (<code>next build</code>) when TypeScript errors are present in your project.</p>\n<p>If you'd like Next.js to dangerously produce production code even when your application has errors, you can disable the built-in type checking step.</p>\n<p>If disabled, be sure you are running type checks as part of your build or deploy process, otherwise this can be very dangerous.</p>\n<p>Open <code>next.config.ts</code> and enable the <code>ignoreBuildErrors</code> option in the <a href=\"/docs/app/api-reference/config/next-config-js/typescript\"><code>typescript</code></a> config:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  typescript</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // !! WARN !!</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Dangerously allow production builds to successfully complete even if</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // your project has type errors.</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // !! WARN !!</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    ignoreBuildErrors</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: You can run <code>tsc --noEmit</code> to check for TypeScript errors yourself before building. This is useful for CI/CD pipelines where you'd like to check for TypeScript errors before deploying.</p>\n</blockquote>\n<h3 id=\"custom-type-declarations\" data-docs-heading=\"\">Custom type declarations<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#custom-type-declarations\"><span></span></a></h3>\n<p>When you need to declare custom types, you might be tempted to modify <code>next-env.d.ts</code>. However, this file is automatically generated, so any changes you make will be overwritten. Instead, you should create a new file, let's call it <code>new-types.d.ts</code>, and reference it in your <code>tsconfig.json</code>:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">tsconfig.json</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">{</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"compilerOptions\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    \"skipLibCheck\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    //...truncated...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"include\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"new-types.d.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"next-env.d.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \".next/types/**/*.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"**/*.ts\"</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    \"**/*.tsx\"</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  ]</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  \"exclude\"</span><span style=\"color:var(--shiki-token-punctuation)\">:</span><span style=\"color:var(--shiki-color-text)\"> [</span><span style=\"color:var(--shiki-token-string-expression)\">\"node_modules\"</span><span style=\"color:var(--shiki-color-text)\">]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"version-changes\" data-docs-heading=\"\">Version Changes<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-changes\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v15.0.0</code></td><td><a href=\"#type-checking-nextjs-configuration-files\"><code>next.config.ts</code></a> support added for TypeScript projects.</td></tr><tr><td><code>v13.2.0</code></td><td>Statically typed links are available in beta.</td></tr><tr><td><code>v12.0.0</code></td><td><a href=\"/docs/architecture/nextjs-compiler\">SWC</a> is now used by default to compile TypeScript and TSX for faster builds.</td></tr><tr><td><code>v10.2.1</code></td><td><a href=\"https://www.typescriptlang.org/tsconfig#incremental\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Incremental type checking<span class=\"inline-flex not-prose\"></span></a> support added when enabled in your <code>tsconfig.json</code>.</td></tr></tbody></table></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/directives",
    "title": "API Reference: Directives | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">Directives</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->June 16, 2025</div><p>The following directives are available:</p></div><div class=\"not-prose mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache\" directive to cache data in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-private\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: private</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: private\" directive to cache functions that access runtime request APIs.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-remote\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: remote</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: remote\" directive for persistent, shared caching using remote cache handlers.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-client\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use client</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the use client directive to render a component on the client.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-server\"><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use server</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the use server directive to execute code on the server.</div></a></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/directives/use-cache",
    "title": "Directives: use cache | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">use cache</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->July 22, 2026</div><p>The <code>use cache</code> directive allows you to mark a route, React component, or a function as cacheable. It can be used at the top of a file to indicate that all exports in the file should be cached, or inline at the top of a function or component to cache the return value. Functions and components that use <code>use cache</code> must be async.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong></p>\n<ul>\n<li>To use cookies or headers, read them outside cached scopes and pass values as arguments. This is the preferred pattern.</li>\n<li>If the in-memory cache isn't sufficient for runtime data, <a href=\"/docs/app/api-reference/directives/use-cache-remote\"><code>'use cache: remote'</code></a> allows platforms to provide a dedicated cache handler, though it requires a network roundtrip to check the cache and typically incurs platform fees.</li>\n<li>For compliance requirements or when you can't refactor to pass runtime data as arguments to a <code>use cache</code> scope, see <a href=\"/docs/app/api-reference/directives/use-cache-private\"><code>'use cache: private'</code></a>.</li>\n</ul>\n</blockquote>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p><code>use cache</code> is a Cache Components feature. To enable it, add the <a href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><code>cacheComponents</code></a> option to your <code>next.config.ts</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheComponents</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>Then, add <code>use cache</code> at the file, component, or function level. All functions and components using <code>use cache</code> must be async. When used at file level, every exported function becomes a cached function and must also be async:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// File level</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // ...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Component level</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> MyComponent</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;&gt;&lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Function level</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"how-use-cache-works\" data-docs-heading=\"\">How <code>use cache</code> works<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#how-use-cache-works\"><span></span></a></h2>\n<h3 id=\"cache-keys\" data-docs-heading=\"\">Cache keys<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#cache-keys\"><span></span></a></h3>\n<p>A cache entry's key is generated using a serialized version of its inputs, which includes:</p>\n<ol>\n<li><strong>Build ID</strong> - Unique per build, changing this invalidates all cache entries. If <a href=\"/docs/app/api-reference/config/next-config-js/deploymentId\"><code>deploymentId</code></a> is configured, it overrides the build ID for cache key purposes.</li>\n<li><strong>Function ID</strong> - A secure hash of the function's location and signature in the codebase</li>\n<li><strong>Serializable arguments</strong> - Props (for components) or function arguments</li>\n<li><strong>HMR refresh hash</strong> (development only) - Invalidates cache on hot module replacement</li>\n</ol>\n<p>When a cached function references variables from outer scopes, those variables are automatically captured and bound as arguments, making them part of the cache key.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">lib/data.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Component</span><span style=\"color:var(--shiki-color-text)\">({ userId }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { userId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> (filter</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Cache key includes both userId (from closure) and filter (argument)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`/api/users/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">userId</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">/data?filter=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">filter</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'active'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>In the snippet above, <code>userId</code> is captured from the outer scope and <code>filter</code> is passed as an argument, so both become part of the <code>getData</code> function's cache key. This means different user and filter combinations will have separate cache entries.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> When a cached function reads <a href=\"/docs/app/api-reference/functions/next-root-params\">root parameters</a>, only the ones it actually reads become part of its cache key.</p>\n</blockquote>\n<h2 id=\"serialization\" data-docs-heading=\"\">Serialization<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#serialization\"><span></span></a></h2>\n<p>Arguments to cached functions and their return values must be serializable.</p>\n<p>For a complete reference, see:</p>\n<ul>\n<li><a href=\"https://react.dev/reference/rsc/use-server#serializable-parameters-and-return-values\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Serializable arguments<span class=\"inline-flex not-prose\"></span></a> - Uses <strong>React Server Components</strong> serialization</li>\n<li><a href=\"https://react.dev/reference/rsc/use-client#serializable-types\" rel=\"noopener noreferrer nofollow\" target=\"_blank\">Serializable return types<span class=\"inline-flex not-prose\"></span></a> - Uses <strong>React Client Components</strong> serialization</li>\n</ul>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> Arguments and return values use different serialization systems. Server Component serialization (for arguments) is more restrictive than Client Component serialization (for return values). This means you can return JSX elements but cannot accept them as arguments unless using pass-through patterns.</p>\n</blockquote>\n<h3 id=\"supported-types\" data-docs-heading=\"\">Supported types<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#supported-types\"><span></span></a></h3>\n<p><strong>Arguments:</strong></p>\n<ul>\n<li>Primitives: <code>string</code>, <code>number</code>, <code>boolean</code>, <code>null</code>, <code>undefined</code></li>\n<li>Plain objects: <code>{ key: value }</code></li>\n<li>Arrays: <code>[1, 2, 3]</code></li>\n<li>Dates, Maps, Sets, TypedArrays, ArrayBuffers</li>\n<li>React elements (as pass-through only)</li>\n</ul>\n<p><strong>Return values:</strong></p>\n<ul>\n<li>Same as arguments, plus JSX elements</li>\n</ul>\n<h3 id=\"unsupported-types\" data-docs-heading=\"\">Unsupported types<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#unsupported-types\"><span></span></a></h3>\n<ul>\n<li>Class instances</li>\n<li>Functions (except as pass-through)</li>\n<li>Symbols, WeakMaps, WeakSets</li>\n<li>URL instances</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/user-card.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Valid - primitives and plain objects</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> UserCard</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  config</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { theme</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{id}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Invalid - class instance</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> UserProfile</span><span style=\"color:var(--shiki-color-text)\">({ user }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { user</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> UserClass</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Error: Cannot serialize class instance</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-constant)\">user</span><span style=\"color:var(--shiki-color-text)\">.name}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h3 id=\"pass-through-non-serializable-arguments\" data-docs-heading=\"\">Pass-through (non-serializable arguments)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#pass-through-non-serializable-arguments\"><span></span></a></h3>\n<p>You can accept non-serializable values <strong>as long as you don't introspect them</strong>. This enables composition patterns with <code>children</code> and Server Actions:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/cached-wrapper.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> CachedWrapper</span><span style=\"color:var(--shiki-color-text)\">({ children }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> ReactNode</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Don't read or modify children - just pass it through</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-token-function)\"> className</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"wrapper\"</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">header</span><span style=\"color:var(--shiki-color-text)\">&gt;Cached Header&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">header</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Usage: children can be dynamic</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">CachedWrapper</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">DynamicComponent</span><span style=\"color:var(--shiki-color-text)\"> /&gt; {</span><span style=\"color:var(--shiki-token-comment)\">/* Not cached, passed through */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">CachedWrapper</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>You can also pass Server Actions through cached components:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/cached-form.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> CachedForm</span><span style=\"color:var(--shiki-color-text)\">({ action }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-function)\">action</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt; }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Don't call action here - just pass it through</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">form</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{action}&gt;{</span><span style=\"color:var(--shiki-token-comment)\">/* ... */</span><span style=\"color:var(--shiki-color-text)\">}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">form</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<h2 id=\"constraints\" data-docs-heading=\"\">Constraints<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#constraints\"><span></span></a></h2>\n<p>Cached functions execute in an isolated environment. The following constraints ensure cache behavior remains predictable and secure.</p>\n<h3 id=\"request-time-apis\" data-docs-heading=\"\">Request-time APIs<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#request-time-apis\"><span></span></a></h3>\n<p>Cached functions and components <strong>cannot</strong> access runtime APIs like <code>cookies()</code>, <code>headers()</code>, or <code>searchParams</code>, and the restriction follows the call stack: a helper the cached function calls that reads one of these fails the same way, with the <a href=\"/docs/messages/next-request-in-use-cache\"><code>next-request-in-use-cache</code></a> error. On a dynamically rendered route this surfaces when the route runs, so it can pass <code>next build</code> and fail under <code>next start</code>. Read these values outside the cached scope and pass them as arguments.</p>\n<h3 id=\"runtime-caching-considerations\" data-docs-heading=\"\">Runtime caching considerations<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#runtime-caching-considerations\"><span></span></a></h3>\n<p>While <code>use cache</code> is designed primarily to include uncached data in the static shell, it can also cache data at runtime using in-memory LRU (Least Recently Used) storage.</p>\n<p>With the default in-memory handler, runtime cache behavior depends on your hosting environment:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Environment</th><th class=\"min-w-[12ch]\">Runtime Caching Behavior</th></tr></thead><tbody><tr><td><strong>Serverless</strong></td><td>Cache entries typically don't persist across requests (each request can be a different instance), or during revalidation. Build-time caching works normally.</td></tr><tr><td><strong>Self-hosted</strong></td><td>Cache entries persist across requests. Control cache size with <a href=\"/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath\"><code>cacheMaxMemorySize</code></a>.</td></tr></tbody></table></div>\n<p>For example, in a serverless environment, a cached function shared by two pages executes on each static shell revalidation, whereas in self-hosted or environments with persistent memory, the cached output is reused if it's still fresh.</p>\n<p>If the default in-memory cache isn't enough, consider <strong><a href=\"/docs/app/api-reference/directives/use-cache-remote\"><code>use cache: remote</code></a></strong> which allows platforms to provide a dedicated cache handler (like Redis or KV database). This helps reduce hits against data sources not scaled to your total traffic, though it comes with costs (storage, network latency, platform fees).</p>\n<div class=\"gap-3 rounded-md relative box-border flex w-full flex-wrap items-center border break-words [&amp;_a:not([data-geist-button])]:font-medium [&amp;_a:not([data-geist-button])]:underline-offset-2 [&amp;_a:not([data-geist-button]):hover]:underline [&amp;_a:not([data-geist-button]):focus-visible]:rounded-[2px] [&amp;_a:not([data-geist-button]):focus-visible]:shadow-(--ds-focus-ring) [&amp;_a:not([data-geist-button]):focus-visible]:outline-none border-gray-alpha-400 text-gray-alpha-900 selection:bg-gray-alpha-900 dark-theme:selection:text-gray-1000 [&amp;_a:not([data-geist-button])]:text-gray-1000 px-3 py-1.5 min-h-(--ds-size-medium) text-copy-14\" data-slot=\"note\" role=\"note\"><div class=\"min-w-0 gap-3 flex flex-1 items-start\" data-slot=\"note-body\"><span class=\"flex shrink-0 [&amp;&gt;svg]:h-[1lh]\" data-slot=\"note-icon\"></span><div class=\"min-w-0 flex-1 not-prose\" data-slot=\"note-content\"><p>With the default in-memory handler, serverless instances are ephemeral, so entries may not be reused between requests, unlike with <code>use cache: remote</code>. Neither caching directive carries over to a new deploy, because the <a href=\"#cache-keys\">cache key</a> includes the build (or <code>deploymentId</code>) ID.</p><p>For data that needs to persist across deploys, use <a href=\"/docs/app/api-reference/functions/unstable_cache\"><code>unstable_cache</code></a> for non-<code>fetch</code> functions or the <a href=\"/docs/app/api-reference/functions/fetch\"><code>fetch</code></a> cache.</p></div></div></div>\n<p>Very rarely, for compliance requirements or when you can't refactor your code to pass runtime data as arguments to a <code>use cache</code> scope, you might need <a href=\"/docs/app/api-reference/directives/use-cache-private\"><code>use cache: private</code></a>.</p>\n<h3 id=\"draft-mode\" data-docs-heading=\"\">Draft Mode<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#draft-mode\"><span></span></a></h3>\n<p>When <a href=\"/docs/app/guides/draft-mode\">Draft Mode</a> is enabled, all cached functions and components re-execute on every request, and results are not saved to the cache. This ensures draft content is always fresh without requiring any changes to your caching code.</p>\n<p>You can read <code>isEnabled</code> from <a href=\"/docs/app/api-reference/functions/draft-mode\"><code>draftMode()</code></a> inside a <code>use cache</code> scope, however, other runtime APIs like <code>cookies()</code> and <code>headers()</code> are not allowed, even when Draft Mode is active. See <a href=\"/docs/app/getting-started/caching#passing-runtime-values-to-cached-functions\">Passing runtime values to cached functions</a> for the recommended pattern.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/content.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { draftMode } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/headers'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Content</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">isEnabled</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> draftMode</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> url</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> isEnabled</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    ?</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://draft.example.com/content'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    :</span><span style=\"color:var(--shiki-token-string-expression)\"> 'https://production.example.com/content'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(url)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">article</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-comment)\">/* ... */</span><span style=\"color:var(--shiki-color-text)\">}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">article</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Calling <code>enable()</code> or <code>disable()</code> inside a caching directive scope will also throw an error. Draft Mode can only be toggled in <a href=\"/docs/app/api-reference/file-conventions/route\">Route Handlers</a> or <a href=\"/docs/app/getting-started/mutating-data\">Server Actions</a>.</p>\n<h3 id=\"reactcache-isolation\" data-docs-heading=\"\">React.cache isolation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#reactcache-isolation\"><span></span></a></h3>\n<p><a href=\"https://react.dev/reference/react/cache\" rel=\"noopener noreferrer nofollow\" target=\"_blank\"><code>React.cache</code><span class=\"inline-flex not-prose\"></span></a> operates in an isolated scope inside <code>use cache</code> boundaries. Values stored via <code>React.cache</code> outside a <code>use cache</code> function are not visible inside it.</p>\n<p>This means you cannot use <code>React.cache</code> to pass data into a <code>use cache</code> scope:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cache } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> store</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> cache</span><span style=\"color:var(--shiki-color-text)\">(() </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> ({ current</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> null</span><span style=\"color:var(--shiki-token-keyword)\"> as</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-token-keyword)\"> |</span><span style=\"color:var(--shiki-token-constant)\"> null</span><span style=\"color:var(--shiki-color-text)\"> }))</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">function</span><span style=\"color:var(--shiki-token-function)\"> Parent</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> shared</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> store</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  shared</span><span style=\"color:var(--shiki-color-text)\">.current </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\"> 'value from parent'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Child</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Child</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> shared</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> store</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // shared.current is null, not 'value from parent'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // use cache has its own isolated React.cache scope</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-constant)\">shared</span><span style=\"color:var(--shiki-color-text)\">.current}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>This isolation ensures cached functions have predictable, self-contained behavior. To pass data into a <code>use cache</code> scope, use function arguments instead.</p>\n<h2 id=\"use-cache-at-runtime\" data-docs-heading=\"\"><code>use cache</code> at runtime<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#use-cache-at-runtime\"><span></span></a></h2>\n<p>On the <strong>server</strong>, cache entries are stored in-memory and respect the <code>revalidate</code> and <code>expire</code> times from your <code>cacheLife</code> configuration. You can customize the cache storage by configuring <a href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><code>cacheHandlers</code></a> in your <code>next.config.js</code> file.</p>\n<p>On the <strong>client</strong>, content from the server cache is stored in the browser's memory for the duration defined by the <code>stale</code> time. The client router enforces a <strong>minimum 30-second stale time</strong>, regardless of configuration.</p>\n<p>The <code>x-nextjs-stale-time</code> response header communicates cache lifetime from server to client, ensuring coordinated behavior.</p>\n<h2 id=\"revalidation\" data-docs-heading=\"\">Revalidation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#revalidation\"><span></span></a></h2>\n<p>Cached functions revalidate based on the <code>revalidate</code> and <code>expire</code> times in their <code>cacheLife</code> profile, or on-demand through tags. These two approaches are not mutually exclusive and are often paired:</p>\n<ul>\n<li><strong><a href=\"#time-based-revalidation\">Time-based</a></strong>: refresh automatically after a set duration with <a href=\"/docs/app/api-reference/functions/cacheLife\"><code>cacheLife</code></a>.</li>\n<li><strong><a href=\"#on-demand-revalidation\">On-demand</a></strong>: invalidate after a mutation with <a href=\"/docs/app/api-reference/functions/cacheTag\"><code>cacheTag</code></a> and <a href=\"/docs/app/api-reference/functions/revalidateTag\"><code>revalidateTag</code></a> or <a href=\"/docs/app/api-reference/functions/updateTag\"><code>updateTag</code></a>.</li>\n</ul>\n<p>For example, a blog post that changes only when its author edits it can use a long <code>cacheLife</code> like <code>max</code> with a <code>cacheTag</code>, then invalidate on demand when the post is saved. A list of recent posts that updates throughout the day can use a shorter profile like <code>hours</code> to refresh on its own, without manual invalidation.</p>\n<h3 id=\"time-based-revalidation\" data-docs-heading=\"\">Time-based revalidation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#time-based-revalidation\"><span></span></a></h3>\n<p>Set an explicit cache lifetime with <a href=\"/docs/app/api-reference/functions/cacheLife\"><code>cacheLife</code></a> in every <code>use cache</code> scope. It makes the cache behavior clear at the call site, instead of depending on the <code>default</code> profile or surrounding caches.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">lib/data.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cacheLife } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cacheLife</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'hours'</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-comment)\">// Use built-in 'hours' profile</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>If you omit <code>cacheLife</code>, the <code>default</code> profile applies and the lifetime is no longer explicit at the call site:</p>\n<ul>\n<li><strong>stale</strong>: 5 minutes (client-side)</li>\n<li><strong>revalidate</strong>: 15 minutes (server-side)</li>\n<li><strong>expire</strong>: never expires by time</li>\n</ul>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">lib/data.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Implicitly uses the 'default' profile</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Nesting a short-lived use cache inside one without an explicit <a href=\"/docs/app/api-reference/functions/cacheLife\">cacheLife</a> fails the build during prerendering. See <a href=\"/docs/app/api-reference/functions/cacheLife#nested-short-lived-caches\">Nested short-lived caches</a> for the rule and fix.</p>\n<h3 id=\"on-demand-revalidation\" data-docs-heading=\"\">On-demand revalidation<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#on-demand-revalidation\"><span></span></a></h3>\n<p>Use <a href=\"/docs/app/api-reference/functions/cacheTag\"><code>cacheTag</code></a>, <a href=\"/docs/app/api-reference/functions/updateTag\"><code>updateTag</code></a>, or <a href=\"/docs/app/api-reference/functions/revalidateTag\"><code>revalidateTag</code></a> for on-demand cache invalidation:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">lib/data.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cacheTag } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getProducts</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cacheTag</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'products'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/products'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/actions.ts</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use server'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { updateTag } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> updateProduct</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  await</span><span style=\"color:var(--shiki-token-constant)\"> db</span><span style=\"color:var(--shiki-token-function)\">.</span><span style=\"color:var(--shiki-token-constant)\">products</span><span style=\"color:var(--shiki-token-function)\">.update</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  updateTag</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'products'</span><span style=\"color:var(--shiki-color-text)\">) </span><span style=\"color:var(--shiki-token-comment)\">// Invalidates all 'products' caches</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Both <code>cacheLife</code> and <code>cacheTag</code> integrate across client and server caching layers, meaning you configure your caching semantics in one place and they apply everywhere.</p>\n<h2 id=\"examples\" data-docs-heading=\"\">Examples<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#examples\"><span></span></a></h2>\n<h3 id=\"caching-an-entire-route-with-use-cache\" data-docs-heading=\"\">Caching an entire route with <code>use cache</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caching-an-entire-route-with-use-cache\"><span></span></a></h3>\n<p>To prerender an entire route, add <code>use cache</code> to the top of <strong>both</strong> the <code>layout</code> and <code>page</code> files. Each of these segments are treated as separate entry points in your application, and will be cached independently.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/layout.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Layout</span><span style=\"color:var(--shiki-color-text)\">({ children }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> ReactNode</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;{children}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>Any components imported and nested in <code>page</code> file are part of the cache output associated with the <code>page</code>.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Users</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> users</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/users'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // loop through users</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Users</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">main</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>:</p>\n<ul>\n<li>If <code>use cache</code> is added only to the <code>layout</code> or the <code>page</code>, only that route segment and any components imported into it will be cached.</li>\n</ul>\n</blockquote>\n<h3 id=\"caching-a-components-output-with-use-cache\" data-docs-heading=\"\">Caching a component's output with <code>use cache</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caching-a-components-output-with-use-cache\"><span></span></a></h3>\n<p>You can use <code>use cache</code> at the component level to cache any fetches or computations performed within that component. The cache entry will be reused as long as the serialized props produce the same value in each instance.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/components/bookings.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Bookings</span><span style=\"color:var(--shiki-color-text)\">({ type </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\"> 'haircut'</span><span style=\"color:var(--shiki-color-text)\"> }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> BookingsProps</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getBookingsData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`/api/bookings?type=</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-token-function)\">encodeURIComponent</span><span style=\"color:var(--shiki-color-text)\">(type)</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    return</span><span style=\"color:var(--shiki-color-text)\"> data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-comment)\"> //...</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">interface</span><span style=\"color:var(--shiki-token-function)\"> BookingsProps</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  type</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h3 id=\"caching-function-output-with-use-cache\" data-docs-heading=\"\">Caching function output with <code>use cache</code><a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#caching-function-output-with-use-cache\"><span></span></a></h3>\n<p>Since you can add <code>use cache</code> to any asynchronous function, you aren't limited to caching components or routes only. You might want to cache a network request, a database query, or a slow computation.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/actions.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"highlighted-line line\" data-line=\"\" data-highlighted-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> data</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> When a cached directive (<code>use cache</code>, <a href=\"/docs/app/api-reference/directives/use-cache-private\"><code>use cache: private</code></a>, or <a href=\"/docs/app/api-reference/directives/use-cache-remote\"><code>use cache: remote</code></a>) is at the top of a file, you can import its exported functions into a Client Component and call them directly; they run on the server and return the result, similar to a <a href=\"/docs/app/glossary#server-function\">Server Function</a>. Prefer calling cached functions on the server and passing results down as props.</p>\n</blockquote>\n<h3 id=\"interleaving\" data-docs-heading=\"\">Interleaving<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#interleaving\"><span></span></a></h3>\n<p>In React, composition with <code>children</code> or slots is a well-known pattern for building flexible components. When using <code>use cache</code>, you can continue to compose your UI in this way. Anything included as <code>children</code>, or other compositional slots, in the returned JSX will be passed through the cached component without affecting its cache entry.</p>\n<p>As long as you don't directly reference any of the JSX slots inside the body of the cacheable function itself, their presence in the returned output won't affect the cache entry.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> uncachedData</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getData</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Pass compositional slots as props, e.g. header and children</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">CacheComponent</span><span style=\"color:var(--shiki-token-function)\"> header</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;Home&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">h1</span><span style=\"color:var(--shiki-color-text)\">&gt;}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-comment)\">/* DynamicComponent is provided as the children slot */</span><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">DynamicComponent</span><span style=\"color:var(--shiki-token-function)\"> data</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{uncachedData} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">CacheComponent</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> CacheComponent</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  header</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // header: a compositional slot, injected as a prop</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-comment)\"> // children: another slot for nested composition</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  header</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  children</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> ReactNode</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> cachedData</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'/api/cached-data'</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {header}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">PrerenderedComponent</span><span style=\"color:var(--shiki-token-function)\"> data</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{cachedData} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {children}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<p>You can also pass Server Actions through cached components to Client Components without invoking them inside the cacheable function.</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> ClientComponent </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> './ClientComponent'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-function)\"> performUpdate</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">    'use server'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">    // Perform some server-side update</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">    await</span><span style=\"color:var(--shiki-token-constant)\"> db</span><span style=\"color:var(--shiki-token-function)\">.update</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-keyword)\">...</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  }</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">CachedComponent</span><span style=\"color:var(--shiki-token-function)\"> performUpdate</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{performUpdate} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> CachedComponent</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  performUpdate</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  performUpdate</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Do not call performUpdate here</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">ClientComponent</span><span style=\"color:var(--shiki-token-function)\"> action</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{performUpdate} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/ClientComponent.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">'use client'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> ClientComponent</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  action</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  action</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> () </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">void</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-token-function)\"> onClick</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{action}&gt;Update&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">button</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<h2 id=\"troubleshooting\" data-docs-heading=\"\">Troubleshooting<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#troubleshooting\"><span></span></a></h2>\n<h3 id=\"debugging-cache-behavior\" data-docs-heading=\"\">Debugging cache behavior<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#debugging-cache-behavior\"><span></span></a></h3>\n<h4 id=\"verbose-logging\" data-docs-heading=\"\">Verbose logging<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#verbose-logging\"><span></span></a></h4>\n<p>Set <code>NEXT_PRIVATE_DEBUG_CACHE=1</code> for verbose cache logging:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] not-prose\" data-geist-code-block=\"\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)] !absolute z-1 !bg-[var(--ds-background-200)] right-4 top-[min(16%,16px)] opacity-0 group-hover/copy:opacity-100 focus:opacity-100\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NEXT_PRIVATE_DEBUG_CACHE</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">1</span><span style=\"color:var(--shiki-token-function)\"> npm</span><span style=\"color:var(--shiki-token-string)\"> run</span><span style=\"color:var(--shiki-token-string)\"> dev</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\"># or for production</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">NEXT_PRIVATE_DEBUG_CACHE</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string)\">1</span><span style=\"color:var(--shiki-token-function)\"> npm</span><span style=\"color:var(--shiki-token-string)\"> run</span><span style=\"color:var(--shiki-token-string)\"> start</span></span></code></pre></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> This environment variable also logs ISR and other caching mechanisms. See <a href=\"/docs/app/guides/incremental-static-regeneration#verifying-correct-production-behavior\">Verifying correct production behavior</a> for more details.</p>\n</blockquote>\n<h4 id=\"console-log-replays\" data-docs-heading=\"\">Console log replays<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#console-log-replays\"><span></span></a></h4>\n<p>In development, console logs from cached functions appear with a <code>Cache</code> prefix.</p>\n<h3 id=\"build-hangs-cache-timeout\" data-docs-heading=\"\">Build Hangs (Cache Timeout)<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#build-hangs-cache-timeout\"><span></span></a></h3>\n<p>If your build hangs, you're accessing Promises that resolve to uncached or runtime data, created outside a <code>use cache</code> boundary. The cached function waits for data that can't resolve during the build, causing a timeout after 50 seconds.</p>\n<p>When the build timeouts you'll see this error message:</p>\n<blockquote class=\"p-3 text-sm\">\n<p>Error: Filling a cache during prerender timed out, likely because request-specific arguments such as params, searchParams, cookies() or uncached data were used inside \"use cache\".</p>\n</blockquote>\n<p>Common ways this happens: passing such Promises as props, accessing them via closure, or retrieving them from shared storage (Maps).</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know:</strong> Directly calling <code>cookies()</code> or <code>headers()</code> inside <code>use cache</code> fails immediately with a <a href=\"/docs/messages/next-request-in-use-cache\">different error</a>, not a timeout.</p>\n</blockquote>\n<p><strong>Passing runtime data Promises as props:</strong></p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cookies } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/headers'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Suspense } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-token-function)\"> fallback</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;Loading...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Dynamic</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dynamic</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> cookieStore</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-function)\"> cookies</span><span style=\"color:var(--shiki-color-text)\">()</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-constant)\">Cached</span><span style=\"color:var(--shiki-token-function)\"> promise</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{cookieStore} /&gt; </span><span style=\"color:var(--shiki-token-comment)\">// Build hangs</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Cached</span><span style=\"color:var(--shiki-color-text)\">({ promise }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { promise</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">unknown</span><span style=\"color:var(--shiki-color-text)\">&gt; }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> data</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> promise </span><span style=\"color:var(--shiki-token-comment)\">// Waits for runtime data during build</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;..&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Await the <code>cookies</code> store in the <code>Dynamic</code> component, and pass a cookie value to the <code>Cached</code> component.</p>\n<p><strong>Shared deduplication storage:</strong></p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/page.tsx</span></div><div class=\"gap-1 flex\"><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">// Problem: Map stores dynamic Promises, accessed by cached code</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Suspense } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> new</span><span style=\"color:var(--shiki-token-function)\"> Map</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">string</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;</span><span style=\"color:var(--shiki-token-constant)\">string</span><span style=\"color:var(--shiki-color-text)\">&gt;&gt;()</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Page</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-token-function)\"> fallback</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;Loading...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Dynamic</span><span style=\"color:var(--shiki-token-function)\"> id</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"data\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Cached</span><span style=\"color:var(--shiki-token-function)\"> id</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-string-expression)\">\"data\"</span><span style=\"color:var(--shiki-color-text)\"> /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Dynamic</span><span style=\"color:var(--shiki-color-text)\">({ id }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Stores dynamic Promise in shared Map</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-constant)\">  cache</span><span style=\"color:var(--shiki-token-function)\">.set</span><span style=\"color:var(--shiki-color-text)\">(</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    id</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">    fetch</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`https://api.example.com/</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">id</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span><span style=\"color:var(--shiki-token-function)\">.then</span><span style=\"color:var(--shiki-color-text)\">((r) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-token-constant)\"> r</span><span style=\"color:var(--shiki-token-function)\">.text</span><span style=\"color:var(--shiki-color-text)\">())</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;Dynamic&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Cached</span><span style=\"color:var(--shiki-color-text)\">({ id }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt;{</span><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-token-constant)\"> cache</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(id)}&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">p</span><span style=\"color:var(--shiki-color-text)\">&gt; </span><span style=\"color:var(--shiki-token-comment)\">// Build hangs - retrieves dynamic Promise</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<p>Use Next.js's built-in <code>fetch()</code> deduplication or use separate Maps for cached and uncached contexts.</p>\n<h2 id=\"platform-support\" data-docs-heading=\"\">Platform Support<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#platform-support\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Deployment Option</th><th class=\"min-w-[12ch]\">Supported</th></tr></thead><tbody><tr><td><a href=\"/docs/app/getting-started/deploying#nodejs-server\">Node.js server</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#docker\">Docker container</a></td><td>Yes</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#static-export\">Static export</a></td><td>No</td></tr><tr><td><a href=\"/docs/app/getting-started/deploying#adapters\">Adapters</a></td><td>Platform-specific</td></tr></tbody></table></div>\n<p>Learn how to <a href=\"/docs/app/guides/self-hosting#caching-and-isr\">configure caching</a> when self-hosting Next.js.</p>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.0.0</code></td><td><code>\"use cache\"</code> is enabled with the Cache Components feature.</td></tr><tr><td><code>v15.0.0</code></td><td><code>\"use cache\"</code> is introduced as an experimental feature.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache-private\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache: private</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache: private\" directive to cache functions that access runtime request APIs.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheComponents</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the cacheComponents flag in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheLife\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to set up cacheLife configurations in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheHandlers\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheHandlers</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Configure custom cache handlers for use cache directives in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/cacheTag\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheTag</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the cacheTag function to manage cache invalidation in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/cacheLife\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the cacheLife function to set the cache expiration time for a cached function or component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/revalidateTag\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">revalidateTag</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">API Reference for the revalidateTag function.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  },
  {
    "url": "https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
    "title": "Directives: use cache: private | Next.js",
    "content": "<div class=\"prose\"><span class=\"sr-only\">This page is also available as Markdown: request this page's URL with an <code>Accept: text/markdown</code> header.<!-- --> <!-- -->For an index of <!-- -->Next.js documentation<!-- -->, see<!-- --> <a href=\"/docs/llms.txt\">/docs/llms.txt</a>.</span><div class=\"not-prose flex flex-col md:flex-row items-start md:justify-between gap-2 md:items-center mb-7 md:mb-10 md:mt-2\"><div class=\"flex relative\" style=\"--divider-color:var(--ds-gray-300)\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-r-none !border-r-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Copy page</span></button><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"menu-_R_56tbsnuiubaaivb_\" aria-label=\"Copy page\" data-geist-menu-button=\"\" data-is-open=\"false\" id=\"menu-button-_R_56tbsnuiubaaivbH1_\" style=\"--geist-icon-size:16px\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md [--themed-bg:_var(--ds-background-100)] shadow-[0_0_0_1px_var(--themed-border,_transparent)] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--themed-fg:_var(--ds-gray-1000)] [--themed-border:_var(--ds-gray-400)] data-[focus]:shadow-[0_0_0_1px_var(--themed-border,_transparent),0_0_0_2px_var(--ds-background-100),0_0_0_4px_var(--ds-focus-color)] data-[focus]:transition-none text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--ds-gray-100)] dark-theme:data-hover:bg-[var(--ds-gray-200)] data-hover:text-[var(--themed-fg)] data-hover:disabled:bg-[var(--ds-gray-100)] data-hover:!bg-background-100 data-hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] relative z-[1] !shadow-none !border-1 !border-gray-400 !rounded-l-none !border-l-0 focus:z-[2] focus:shadow-[var(--ds-focus-ring)] before:content-[&quot;&quot;] before:absolute before:top-0 before:left-[-1px] before:h-full before:w-[1px] disabled:before:opacity-10 before:bg-[var(--divider-color)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\"><span class=\"truncate px-1.5 shrink-0 flex items-center justify-center\"><span class=\"flex items-center justify-between gap-1 flex-nowrap w-full\"></span></span></button></div></div><div data-docs=\"true\"><h1 class=\"wrap-break-word hyphens-auto\">use cache: private</h1><div class=\"text-sm text-gray-900 mt-2 mb-6\">Last updated <!-- -->August 10, 2026</div><p>The <code>'use cache: private'</code> directive allows functions to access runtime request APIs like <code>cookies()</code>, <code>headers()</code>, and <code>searchParams</code> within a cached scope. However, results are <strong>never stored on the server</strong>, they're cached only in the browser's memory and do not persist across page reloads.</p>\n<p>Reach for <code>'use cache: private'</code> when:</p>\n<ul>\n<li>You want to cache a function that already accesses runtime data, and refactoring to <a href=\"/docs/app/getting-started/caching#working-with-runtime-apis\">move the runtime access outside and pass values as arguments</a> is not practical.</li>\n<li>Compliance requirements prevent storing certain data on the server, even temporarily</li>\n</ul>\n<p>Because this directive accesses runtime data, the function executes on every server render and is excluded from running during <a href=\"/docs/app/getting-started/caching#prerendering\">static shell</a> generation.</p>\n<p>It is <strong>not</strong> possible to configure custom cache handlers for <code>'use cache: private'</code>.</p>\n<p>For a comparison of the different cache directives, see <a href=\"/docs/app/api-reference/directives/use-cache-remote#how-use-cache-remote-differs-from-use-cache-and-use-cache-private\">How <code>use cache: remote</code> differs from <code>use cache</code> and <code>use cache: private</code></a>.</p>\n<h2 id=\"usage\" data-docs-heading=\"\">Usage<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#usage\"><span></span></a></h2>\n<p>To use <code>'use cache: private'</code>, enable the <a href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><code>cacheComponents</code></a> flag in your <code>next.config.ts</code> file:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">next.config.ts</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-token-keyword)\"> type</span><span style=\"color:var(--shiki-color-text)\"> { NextConfig } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">const</span><span style=\"color:var(--shiki-token-constant)\"> nextConfig</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> NextConfig</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  cacheComponents</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> true</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-color-text)\"> nextConfig</span></span></code></pre></div>\n<!-- -->\n<p>Then add <code>'use cache: private'</code> to your function along with a <code>cacheLife</code> configuration.</p>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: This directive is not available in Route Handlers.</p>\n</blockquote>\n<h3 id=\"basic-example\" data-docs-heading=\"\">Basic example<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#basic-example\"><span></span></a></h3>\n<p>In this example, we demonstrate that you can access cookies within a <code>'use cache: private'</code> scope:</p>\n<div class=\"my-4 rounded-md group/copy relative overflow-hidden border border-[var(--ds-gray-400)] rounded-b-md bg-[var(--ds-bfackground-100)] not-prose\" data-geist-code-block=\"\"><div class=\"py-0 pl-4 rounded-t-md h-12 flex items-center border-b border-[var(--ds-gray-400)] bg-[var(--ds-background-200)] pr-3\"><div class=\"gap-2 m-0 min-w-0 mr-auto flex items-center text-[13px] text-[var(--ds-gray-900)]\"><div aria-hidden=\"true\" class=\"w-4 flex shrink-0 items-center\"></div><span class=\"min-w-0 inline-block max-w-full truncate break-normal\">app/product/[id]/page.tsx</span></div><div class=\"gap-1 flex\"><div class=\"relative group\"><div aria-hidden=\"true\" class=\"py-0 px-2 border-none rounded-[5px] text-[13px] h-full flex items-center leading-none gap-1 bg-[var(--ds-background-200)] transition-colors duration-200 cursor-pointer text-[var(--ds-gray-900)] font-sans whitespace-nowrap group-focus-within:shadow-[var(--ds-focus-ring)] group-hover:bg-[var(--ds-gray-200)]\"><span>TypeScript</span></div><select class=\"absolute inset-0 outline-hidden opacity-0 cursor-pointer bg-gray-100\"><option value=\"JavaScript\" class=\"text-gray-1000\">JavaScript</option><option value=\"TypeScript\" class=\"text-gray-1000\" selected=\"\">TypeScript</option></select></div><button type=\"button\" tabindex=\"0\" data-react-aria-pressable=\"true\" aria-label=\"Copy to clipboard\" data-testid=\"copy/button\" class=\"outline-none m-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] font-medium max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:10px] [--height:var(--ds-size-medium)] text-[14px] !px-0 geist-new-themed geist-new-tertiary geist-new-tertiary-fill rounded-md bg-transparent !text-[var(--themed-bg,_var(--ds-gray-1000))] [--themed-border:_transparent] [--themed-hover-bg:_var(--ds-gray-alpha-200)] [--lighten-color:_rgba(255,_255,_255,_0.8)] data-hover:![--themed-border:_var(--ds-gray-alpha-200)] p-0 w-[var(--geist-form-height)] h-[var(--geist-form-height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)] !size-8 !rounded-[5px] [&amp;_svg]:!text-[var(--ds-gray-900)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate px-1.5 inline-flex items-center justify-center shrink-0\"><div class=\"relative size-4\"><div class=\"absolute transition-all duration-200 ease-in-out opacity-0 scale-50\"></div><div class=\"absolute transition-all duration-200 ease-in-out opacity-100 scale-100\"></div></div></span></button></div></div><pre class=\"code-block-module__vF3MAa__pre\"><code class=\"font-mono grid text-left !text-[13px] leading-[20px] break-normal hyphens-none whitespace-pre text-[var(--ds-gray-1000)]\" style=\"font-feature-settings:&quot;liga&quot; off\"><span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { Suspense } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'react'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cookies } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/headers'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">import</span><span style=\"color:var(--shiki-color-text)\"> { cacheLife</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> cacheTag } </span><span style=\"color:var(--shiki-token-keyword)\">from</span><span style=\"color:var(--shiki-token-string-expression)\"> 'next/cache'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> generateStaticParams</span><span style=\"color:var(--shiki-color-text)\">() {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> [{ id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-string-expression)\"> '1'</span><span style=\"color:var(--shiki-color-text)\"> }]</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">export</span><span style=\"color:var(--shiki-token-keyword)\"> default</span><span style=\"color:var(--shiki-token-keyword)\"> async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> ProductPage</span><span style=\"color:var(--shiki-color-text)\">({</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  params</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-function)\"> Promise</span><span style=\"color:var(--shiki-color-text)\">&lt;{ id</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-color-text)\"> { </span><span style=\"color:var(--shiki-token-constant)\">id</span><span style=\"color:var(--shiki-color-text)\"> } </span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-color-text)\"> params</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">ProductDetails</span><span style=\"color:var(--shiki-token-function)\"> id</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{id} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-token-function)\"> fallback</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{&lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;Loading recommendations...&lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;}&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">Recommendations</span><span style=\"color:var(--shiki-token-function)\"> productId</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{id} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      &lt;/</span><span style=\"color:var(--shiki-token-constant)\">Suspense</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> Recommendations</span><span style=\"color:var(--shiki-color-text)\">({ productId }</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-color-text)\"> { productId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\"> }) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> recommendations</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-token-keyword)\"> await</span><span style=\"color:var(--shiki-token-function)\"> getRecommendations</span><span style=\"color:var(--shiki-color-text)\">(productId)</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      {</span><span style=\"color:var(--shiki-token-constant)\">recommendations</span><span style=\"color:var(--shiki-token-function)\">.map</span><span style=\"color:var(--shiki-color-text)\">((rec) </span><span style=\"color:var(--shiki-token-keyword)\">=&gt;</span><span style=\"color:var(--shiki-color-text)\"> (</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">        &lt;</span><span style=\"color:var(--shiki-token-constant)\">ProductCard</span><span style=\"color:var(--shiki-token-function)\"> key</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{</span><span style=\"color:var(--shiki-token-constant)\">rec</span><span style=\"color:var(--shiki-color-text)\">.id} </span><span style=\"color:var(--shiki-token-function)\">product</span><span style=\"color:var(--shiki-token-keyword)\">=</span><span style=\"color:var(--shiki-color-text)\">{rec} /&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">      ))}</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">    &lt;/</span><span style=\"color:var(--shiki-token-string-expression)\">div</span><span style=\"color:var(--shiki-color-text)\">&gt;</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">  )</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">async</span><span style=\"color:var(--shiki-token-keyword)\"> function</span><span style=\"color:var(--shiki-token-function)\"> getRecommendations</span><span style=\"color:var(--shiki-color-text)\">(productId</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> string</span><span style=\"color:var(--shiki-color-text)\">) {</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-string-expression)\">  'use cache: private'</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cacheTag</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">`recommendations-</span><span style=\"color:var(--shiki-token-keyword)\">${</span><span style=\"color:var(--shiki-color-text)\">productId</span><span style=\"color:var(--shiki-token-keyword)\">}</span><span style=\"color:var(--shiki-token-string-expression)\">`</span><span style=\"color:var(--shiki-color-text)\">)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-function)\">  cacheLife</span><span style=\"color:var(--shiki-color-text)\">({ stale</span><span style=\"color:var(--shiki-token-keyword)\">:</span><span style=\"color:var(--shiki-token-constant)\"> 60</span><span style=\"color:var(--shiki-color-text)\"> })</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-comment)\">  // Access cookies within private cache functions</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  const</span><span style=\"color:var(--shiki-token-constant)\"> sessionId</span><span style=\"color:var(--shiki-token-keyword)\"> =</span><span style=\"color:var(--shiki-color-text)\"> (</span><span style=\"color:var(--shiki-token-keyword)\">await</span><span style=\"color:var(--shiki-token-function)\"> cookies</span><span style=\"color:var(--shiki-color-text)\">())</span><span style=\"color:var(--shiki-token-function)\">.get</span><span style=\"color:var(--shiki-color-text)\">(</span><span style=\"color:var(--shiki-token-string-expression)\">'session-id'</span><span style=\"color:var(--shiki-color-text)\">)?.value </span><span style=\"color:var(--shiki-token-keyword)\">||</span><span style=\"color:var(--shiki-token-string-expression)\"> 'guest'</span></span>\n<span class=\"line\" data-line=\"\"> </span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-token-keyword)\">  return</span><span style=\"color:var(--shiki-token-function)\"> getPersonalizedRecommendations</span><span style=\"color:var(--shiki-color-text)\">(productId</span><span style=\"color:var(--shiki-token-punctuation)\">,</span><span style=\"color:var(--shiki-color-text)\"> sessionId)</span></span>\n<span class=\"line\" data-line=\"\"><span style=\"color:var(--shiki-color-text)\">}</span></span></code></pre></div>\n<!-- -->\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Good to know</strong>: The <code>stale</code> time must be at least 30 seconds for per-link prefetching to work, and at least 5 minutes for the content to be included in the route's <a href=\"/docs/app/glossary#app-shell\">App Shell</a>. See <a href=\"/docs/app/api-reference/functions/cacheLife#prerendering-behavior\"><code>cacheLife</code> prerendering behavior</a> for details.</p>\n</blockquote>\n<h2 id=\"request-apis-allowed-in-private-caches\" data-docs-heading=\"\">Request APIs allowed in private caches<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#request-apis-allowed-in-private-caches\"><span></span></a></h2>\n<p>The following request-specific APIs can be used inside <code>'use cache: private'</code> functions:</p>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">API</th><th class=\"min-w-[12ch]\">Allowed in <code>use cache</code></th><th class=\"min-w-[12ch]\">Allowed in <code>'use cache: private'</code></th></tr></thead><tbody><tr><td><code>cookies()</code></td><td>No</td><td>Yes</td></tr><tr><td><code>headers()</code></td><td>No</td><td>Yes</td></tr><tr><td><code>searchParams</code></td><td>No</td><td>Yes</td></tr><tr><td><code>connection()</code></td><td>No</td><td>No</td></tr></tbody></table></div>\n<blockquote class=\"p-3 text-sm\">\n<p><strong>Note:</strong> The <a href=\"https://nextjs.org/docs/app/api-reference/functions/connection\" rel=\"noopener noreferrer\" target=\"_blank\"><code>connection()</code><span class=\"inline-flex not-prose\"></span></a> API is prohibited in both <code>use cache</code> and <code>'use cache: private'</code> as it provides connection-specific information that cannot be safely cached.</p>\n</blockquote>\n<h2 id=\"version-history\" data-docs-heading=\"\">Version History<a aria-label=\"Link to this section\" data-heading-link=\"\" href=\"#version-history\"><span></span></a></h2>\n<div class=\"overflow-x-auto\"><table class=\"w-full table-auto\"><thead><tr><th class=\"min-w-[12ch]\">Version</th><th class=\"min-w-[12ch]\">Changes</th></tr></thead><tbody><tr><td><code>v16.0.0</code></td><td><code>\"use cache: private\"</code> is enabled with the Cache Components feature.</td></tr></tbody></table></div></div><div class=\"mt-16\"><h2 class=\"text-3xl font-bold\" id=\"related\" data-docs-heading=\"\">Related</h2><div class=\"mt-2 text-gray-900\">View related API references.</div><div class=\"mt-8 grid grid-cols-1 gap-8 sm:grid-cols-2\"><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/directives/use-cache\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">use cache</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the \"use cache\" directive to cache data in your Next.js application.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/config/next-config-js/cacheComponents\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheComponents</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to enable the cacheComponents flag in Next.js.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/cacheLife\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheLife</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the cacheLife function to set the cache expiration time for a cached function or component.</div></a><a class=\"not-prose bg-gray-0 shadow-(--ds-shadow-border) group block space-y-2 rounded-md p-6 pt-5 transition-shadow duration-300 hover:shadow-(--ds-shadow-border-large)\" href=\"/docs/app/api-reference/functions/cacheTag\"><div class=\"flex flex-wrap items-center gap-0.5 text-xs\"></div><h3 class=\"group-hover:text-gray-1000 truncate text-lg font-medium leading-snug\">cacheTag</h3><div class=\"line-clamp-3 text-sm font-normal text-gray-900\">Learn how to use the cacheTag function to manage cache invalidation in your Next.js application.</div></a></div></div></div><div class=\"flex justify-center\" data-feedback-inline=\"\"><div class=\"shadow-[var(--ds-shadow-border-small)] transition-colors duration-200 w-fit overflow-hidden bg-[var(--ds-background-100)]\" style=\"height:48px;width:274px;border-radius:30px\"><div class=\"flex items-center justify-center gap-2 py-2 pl-4 pr-2\"><p class=\"text-copy-14 text-gray-900\">Was this helpful?</p><span class=\"flex items-center text-[var(--ds-gray-900)] gap-[1px]\"><button aria-checked=\"false\" aria-label=\"Select Hate it emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Not great emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select It's okay emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button><button aria-checked=\"false\" aria-label=\"Select Love it! emoji\" class=\"bg-transparent border-none radius rounded-[50%] size-8 p-0 flex items-center justify-center cursor-pointer text-[var(--ds-gray-900)] [&amp;_svg_path]:transition-all transition-[background,border-color] duration-200 hover:bg-[var(--ds-blue-300)] hover:border-[var(--ds-blue-300)] hover:[&amp;_svg_path]:fill-[var(--ds-blue-900)] aria-[checked='true']:bg-[var(--ds-blue-300)] aria-[checked='true']:border-[var(--ds-blue-300)] aria-[checked='true']:[&amp;_svg_path]:fill-[var(--ds-blue-900)] focus-visible:outline-hidden focus-visible:shadow-[var(--ds-focus-ring)]\" role=\"radio\" type=\"button\"></button></span></div><div><form class=\"h-full\"><div class=\"p-2 flex flex-col gap-2\"><label data-version=\"v1\"><div class=\"flex max-w-full transition-all duration-150 shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] overflow-hidden font-normal rounded-md [&amp;&gt;input]:h-(--ds-size-medium) text-sm [&amp;&gt;input]:px-3 has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(0,0,0,0.16)] dark-theme:has-[:focus]:!shadow-[0_0_0_1px_var(--ds-gray-alpha-600),0px_0px_0px_4px_rgba(255,255,255,0.24)] hover:shadow-[0_0_0_1px_var(--ds-gray-alpha-500)] hover:[&amp;:has(input:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] hover:[&amp;:has(textarea:disabled)]:shadow-[0_0_0_1px_var(--ds-gray-alpha-400)] w-full\" data-geist-textarea-wrapper=\"\"><textarea autocapitalize=\"off\" autocomplete=\"off\" autocorrect=\"off\" class=\"py-2.5 px-3 resize-none w-full [&amp;[rows]]:h-[unset] inline-flex appearance-none webkit-search-reset min-w-0 border-none bg-[var(--ds-background-100)] text-[var(--geist-foreground)] order-1 outline-none focus:outline-none disabled:bg-[var(--ds-gray-100)] disabled:placeholder:text-[var(--accents-3)] disabled:[-webkit-text-fill-color:var(--accents-3)] disabled:opacity-100 disabled:text-[var(--ds-gray-700)] disabled:cursor-not-allowed h-[100px]\" spellcheck=\"false\" placeholder=\"Your feedback...\" id=\"feedback-textarea\"></textarea></div></label><div class=\"text-label-12 text-gray-900 flex justify-end items-center gap-1 p-0\">supported.</div></div><div class=\"flex justify-between bg-[var(--accents-1)] border-t border-[var(--accents-2)] p-3\" style=\"justify-content:flex-end\"><button type=\"submit\" tabindex=\"0\" data-react-aria-pressable=\"true\" class=\"outline-none m-0 p-0 border-0 align-baseline no-underline group/trigger relative cursor-pointer select-none transform translate-z-0 flex text-[var(--themed-fg,_var(--ds-background-100))] bg-[var(--themed-bg,_var(--ds-gray-1000))] font-medium !px-(--geist-gap-half) max-w-full items-center justify-center transition-[border-color, background,color,transform,box-shadow] duration-[time:150ms] ease-in-out data-[focus]:transition-none data-[focus]:shadow-[var(--ds-focus-ring)] [&amp;_svg]:shrink-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:text-[var(--ds-gray-700)] disabled:bg-[var(--ds-gray-100)] aria-disabled:text-[var(--ds-gray-700)] aria-disabled:bg-[var(--ds-gray-100)] disabled:![--themed-border:_var(--ds-gray-400)] [--x-padding:6px] [--height:32px] !pl-[var(--x-padding)] !pr-[var(--x-padding)] rounded-md text-(length:--geist-form-small-font) [--spinner-size:16px] h-[var(--height)] data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:data-hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))] data-hover:[--themed-border:var(--themed-hover-bg,_var(--ds-gray-200))] data-hover:disabled:bg-[var(--ds-gray-100)]\" data-geist-button=\"\" data-prefix=\"false\" data-suffix=\"false\" data-version=\"v1\" style=\"--geist-icon-size:16px\"><span class=\"truncate inline-block px-1.5\">Send</span></button></div></form></div></div></div>",
    "success": true,
    "error": "",
    "crawled_at": 1786430759.4200137,
    "is_shell": false
  }
]