new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js · API reference · all subjects

file-conventions

373 notes in this subject, read out of this brain and free to use. This is page 5 of 7.

Route Groups use cases

Route Groups are used for: organizing routes by team, concern, or feature; defining multiple root layouts; and opting specific route segments into sharing a layout while keeping others out.

Route Groups top-level root layout requirement

If you use multiple root layouts without a top-level layout.js file, you must define your home route (/) within one of the route groups, such as app/(marketing)/page.js.

Route Groups folder syntax

A route group is created by wrapping a folder name in parentheses, e.g., (folderName). The parentheses syntax indicates the folder is for organizational purposes only.

Route Groups not included in URL path

Route Groups are not included in the route's URL path. The parenthesized folder name is used only for organizational purposes and does not affect the resulting URL.

Route Groups full page load on different root layouts

If you navigate between routes that use different root layouts, it triggers a full page reload. This only applies to multiple root layouts. For example, navigating from /cart using app/(shop)/layout.js to /blog using app/(marketing)/layout.js causes a full page reload.

Slots convention for parallel routes

Parallel routes are created using named slots, defined with the @folder convention. For example, @analytics and @team are slot names. Slots are passed as props to the shared parent layout and can be rendered in parallel alongside the children prop.

Tab groups with parallel routes

You can add a layout inside a slot to allow users to navigate the slot independently. This is useful for creating tabs. The layout file within a slot shares navigation components between multiple subpages within that slot.

Conditional rendering with parallel routes

Parallel Routes can be used to conditionally render routes based on certain conditions. Both slots render on the server regardless of which one the layout returns. The conditional decides what the user sees, not what runs: all slot pages execute their data fetches, and their output is included in the response sent to the browser. Authorization should be inside each slot's page or in a Data Access Layer.

useSelectedLayoutSegment with parallel routes

Both useSelectedLayoutSegment and useSelectedLayoutSegments accept a parallelRoutesKey parameter, which allows you to read the active route segment within a slot. When a user navigates to app/@auth/login (or /login in the URL bar), useSelectedLayoutSegment('auth') will return the string 'login'.

Hard navigation behavior in parallel routes

After a full-page load (browser refresh), Next.js cannot determine the active state for slots that do not match the current URL. Instead, it renders a default.js file for unmatched slots, or 404 if default.js does not exist.

Soft navigation behavior in parallel routes

During soft navigation (client-side navigation), Next.js performs a partial render, changing the subpage within a slot while maintaining the other slots' active subpages, even if they do not match the current URL.

default.js in parallel routes

You can define a default.js file to render as a fallback for unmatched slots during the initial load or full-page reload. If default.js does not exist for an unmatched slot, a 404 is rendered instead.

Dynamic and static slots constraint

If one slot at a route segment level is dynamic, all slots at that level must be dynamic. You cannot have separate prerendered and dynamically rendered slots at the same route segment level.

Children is an implicit slot

The children prop is an implicit slot that does not need to be mapped to a folder. This means app/page.js is equivalent to app/@children/page.js.

Slots do not affect URL structure

Slots are not route segments and do not affect the URL structure. For example, for @analytics/views, the URL will be /views since @analytics is a slot.

Modals with parallel routes and intercepting routes

Parallel Routes can be used together with Intercepting Routes to create modals that support deep linking. This pattern makes modal content shareable through a URL, preserves context when the page is refreshed, closes the modal on backwards navigation, and reopens the modal on forwards navigation.

Parallel Routes definition

Parallel Routes allow you to simultaneously or conditionally render one or more pages within the same layout. They are useful for highly dynamic sections of an app, such as dashboards and feeds on social sites.

Example: Layout accepting parallel route slots

A layout component receiving parallel route slots accepts them as props and renders them. Example code: export default function Layout({ children, team, analytics }: { children: React.ReactNode, analytics: React.ReactNode, team: React.ReactNode }) { return (<>{children}{team}{analytics}</>) }

Example: useSelectedLayoutSegment with parallelRoutesKey

Example using useSelectedLayoutSegment with parallel routes: 'use client' import { useSelectedLayoutSegment } from 'next/navigation' export default function Layout({ auth }: { auth: React.ReactNode }) { const loginSegment = useSelectedLayoutSegment('auth') }

Example: Conditional layout with parallel routes

Example of conditional rendering based on user role: import { checkUserRole } from '@/lib/auth' export default function Layout({ user, admin }: { user: React.ReactNode, admin: React.ReactNode }) { const role = checkUserRole() return role === 'admin' ? admin : user }

Example: Tab group layout in slot

Example layout file within a slot to create tabs: import Link from 'next/link' export default function Layout({ children }: { children: React.ReactNode }) { return (<><nav><Link href="/page-views">Page Views</Link><Link href="/visitors">Visitors</Link></nav><div>{children}</div></>) }

Example: Modal default fallback

Example of @auth/default.tsx file that returns null to ensure the modal is not rendered when inactive: export default function Default() { return null }

Example: Modal with intercepting routes

Example of intercepting the /login route in an @auth slot using modal: import { Modal } from '@/app/ui/modal' import { Login } from '@/app/ui/login' export default function Page() { return (<Modal><Login /></Modal>) }

Example: Layout rendering auth slot modal

Example layout file rendering an @auth slot as a parallel route: import Link from 'next/link' export default function Layout({ auth, children }: { auth: React.ReactNode, children: React.ReactNode }) { return (<><nav><Link href="/login">Open modal</Link></nav><div>{auth}</div><div>{children}</div></>) }

Example: Closing modal with router.back()

Example modal component that closes via router.back(): 'use client' import { useRouter } from 'next/navigation' export function Modal({ children }: { children: React.ReactNode }) { const router = useRouter() return (<><button onClick={() => { router.back() }}>Close modal</button><div>{children}</div></>) }

Example: Catch-all route for modal closing

Example catch-all route to close modal when navigating to any unmatched page: export default function CatchAll() { return null }

Parallel routes streaming and independent states

Parallel Routes can be streamed independently, allowing you to define independent error and loading states for each route. Each parallel route can have its own loading UI and error boundaries.

Intercepting routes convention with parallel routes

The convention (.) is used for intercepting routes within parallel routes. This allows a route to intercept and handle navigation differently based on how the user navigated to it.

Modal content should be Server Components

When using modals with parallel routes, separate the Modal functionality from the modal content. This ensures any content inside the modal, such as forms, are Server Components, enabling proper interleaving of Server and Client Components.

src folder as alternative to root app/pages directories

Next.js supports placing the app Router folder or pages Router folder under a src folder. Move the app or pages directory to src/app or src/pages respectively to use this pattern. This separates application code from project configuration files that typically live in the root.

src folder directory structure requirements

When using the src folder: the /public directory must remain in the root; config files like package.json, next.config.js, and tsconfig.json must remain in the root; .env.* files must remain in the root; src/app or src/pages will be ignored if app or pages directories exist in the root directory.

src folder with application folders and configuration

When using src, you should move other application folders such as /components or /lib into the src folder as well. If using Proxy, it should be placed inside the src folder. If using Tailwind CSS, add the /src prefix to the content section in tailwind.config.js. If using TypeScript paths for imports such as @/*, update the paths object in tsconfig.json to include src/.

Custom profile configuration example

const nextConfig = { cacheComponents: true, cacheLife: { biweekly: { stale: 60 * 60 * 24 * 14, // 14 days revalidate: 60 * 60 * 24, // 1 day expire: 60 * 60 * 24 * 14, // 14 days }, }, } export default nextConfig

Preset profiles can be overridden in next.config.ts

Any preset profile (default, max, seconds, minutes, hours, days, weeks) can be redefined in next.config.ts. Redefining default changes the lifetime applied when a 'use cache' scope calls no cacheLife. The function's type signature is regenerated during next dev, next build, or next typegen to reflect overridden values.

Custom cache profiles in next.config.ts

Custom cache profiles can be defined in next.config.ts under the cacheLife configuration. Any omitted properties in a custom profile inherit from the default profile. Custom profiles can then be referenced by name in cacheLife() calls throughout the application.

config export in proxy file

Optionally, a config object can be exported alongside the Proxy function. This object includes the matcher to specify paths where the Proxy applies.

matcher option formats

The matcher option can be: a single path as a string like '/about'; multiple paths as an array like matcher: ['/about', '/contact']; or complex patterns using regular expressions. For example: matcher: '/((?!api|_next/static|_next/image|.*\\.png$).*)' excludes API routes, static files, image optimizations, and .png files.

matcher object configuration

The matcher option accepts an array of objects with keys: source (string or pattern for matching request paths), locale (optional boolean to ignore locale-based routing when false), has (optional conditions based on headers, query parameters, or cookies), and missing (optional conditions for absent request elements).

source path pattern rules

Source path patterns: 1) MUST start with /; 2) Can include named parameters like /about/:path which matches /about/a and /about/b but not /about/a/c; 3) Can have modifiers on named parameters: * is zero or more, ? is zero or one, + is one or more; 4) Can use regular expressions in parenthesis like /about/(.*); 5) Are anchored to the start of the path: /about matches /about and /about/team but not /blog/about.

matcher constants requirement

Matcher values must be constants so they can be statically analyzed at build-time. Dynamic values such as variables will be ignored.

NextResponse capabilities in proxy

The NextResponse API allows you to: redirect the incoming request to a different URL; rewrite the response by displaying a given URL; set request headers for API Routes, getServerSideProps, and rewrite destinations; set response cookies; set response headers.

proxy execution order in request chain

The execution order is: 1) headers from next.config.js; 2) redirects from next.config.js; 3) Proxy (rewrites, redirects, etc.); 4) beforeFiles (rewrites) from next.config.js; 5) Filesystem routes (public/, _next/static/, pages/, app/); 6) afterFiles (rewrites) from next.config.js; 7) Dynamic Routes (/blog/[slug]); 8) fallback (rewrites) from next.config.js.

Server Functions and Proxy matcher interaction

Server Functions are not separate routes in the execution chain. They are handled as POST requests to the route where they are used, so a Proxy matcher that excludes a path will also skip Server Function calls on that path. A matcher change or refactor that moves a Server Function to a different route can silently remove Proxy coverage. Always verify authentication and authorization inside each Server Function rather than relying on Proxy alone.

proxy runtime default

Proxy defaults to using the Node.js runtime. The runtime config option is not available in Proxy files. Setting the runtime config option in Proxy will throw an error.

skipTrailingSlashRedirect flag in proxy

The skipTrailingSlashRedirect flag disables Next.js redirects for adding or removing trailing slashes. This allows custom handling inside proxy to maintain the trailing slash for some paths but not others. Set in next.config.js: module.exports = { skipTrailingSlashRedirect: true }

skipProxyUrlNormalize flag

The skipProxyUrlNormalize flag allows for disabling URL normalization in Next.js to make handling direct visits and client-transitions the same. In advanced cases, this option provides full control by using the original URL. Set in next.config.js: module.exports = { skipProxyUrlNormalize: true }

RSC requests and rewrites in proxy

During RSC requests, Next.js strips internal Flight headers from the request instance in Proxy. Headers like rsc, next-router-state-tree, and next-router-prefetch are not exposed through request.headers. This is to prevent accidentally handling an RSC request differently than the HTML request. When using NextResponse.rewrite(), Next.js automatically propagates the required RSC rewrite headers upstream.

NextFetchEvent and waitUntil method

NextFetchEvent extends the native FetchEvent object and includes the waitUntil() method. The waitUntil() method takes a promise as an argument and extends the lifetime of the Proxy until the promise settles. This is useful for performing background work like logging or analytics that should finish after the response is sent.

proxy cookies API on response

For outgoing responses, the cookies API has methods: get (get a single cookie), getAll (get all cookies), set (set a cookie), and delete (remove a cookie).

proxy _next/data matcher behavior

Even when _next/data is excluded in a negative matcher pattern, proxy will still be invoked for _next/data routes. This is intentional behavior to prevent accidental security issues where you might protect a page but forget to protect the corresponding data route.

proxy unit testing utilities

Starting in Next.js 15.1, the next/experimental/testing/server package contains utilities for unit testing proxy files. The unstable_doesProxyMatch function can assert whether proxy will run for a provided URL, headers, and cookies. Functions isRewrite and getRewrittenUrl can test proxy rewrite logic.

proxy platform support

Proxy is supported on: Node.js server (Yes); Docker container (Yes); Static export (No); Adapters (Platform-specific).

matcher /public backward compatibility

For backward compatibility, Next.js always considers /public as /public/index. Therefore, a matcher of /public/:path will match.

middleware to proxy migration

The middleware file convention is deprecated and has been renamed to proxy. Run: npx @next/codemod@canary middleware-to-proxy . to migrate. The codemod renames the file from middleware.ts to proxy.ts and the function name from middleware to proxy.

proxy version history

Version 16.0.0: Middleware is deprecated and renamed to Proxy. Proxy defaults to Node.js runtime. Version 15.5.0: Middleware can now use Node.js runtime (stable). Version 15.2.0: Middleware can now use Node.js runtime (experimental). Version 13.1.0: Advanced Middleware flags added. Version 13.0.0: Middleware can modify request headers, response headers, and send responses. Version 12.2.0: Middleware is stable. Version 12.0.9: Enforce absolute URLs in Edge Runtime. Version 12.0.0: Middleware (Beta) added.

proxy conditional statements example

Example of proxy with conditional statements: export function proxy(request) { if (request.nextUrl.pathname.startsWith('/about')) { return NextResponse.rewrite(new URL('/about-2', request.url)) } if (request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.rewrite(new URL('/dashboard/user', request.url)) } }

proxy response directly example

Example of responding from Proxy directly: export function proxy(request) { if (!isAuthenticated(request)) { return Response.json({ success: false, message: 'authentication failed' }, { status: 401 }) } }

proxy with CORS headers example

Example of setting CORS headers in Proxy with handling for preflighted requests: const allowedOrigins = ['https://acme.com', 'https://my-app.org']; const corsOptions = { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' }; export function proxy(request) { const origin = request.headers.get('origin') ?? ''; const isAllowedOrigin = allowedOrigins.includes(origin); const isPreflight = request.method === 'OPTIONS'; if (isPreflight) { const preflightHeaders = { ...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }), ...corsOptions }; return NextResponse.json({}, { headers: preflightHeaders }) } const response = NextResponse.next(); if (isAllowedOrigin) { response.headers.set('Access-Control-Allow-Origin', origin) } Object.entries(corsOptions).forEach(([key, value]) => { response.headers.set(key, value) }); return response }

proxy with waitUntil example

Example of using waitUntil for background work: export function proxy(req, event) { event.waitUntil( fetch('https://my-analytics-platform.com', { method: 'POST', body: JSON.stringify({ pathname: req.nextUrl.pathname }) }) ); return NextResponse.next() }

proxy with cookies example

Example of handling cookies in proxy: let cookie = request.cookies.get('nextjs'); const allCookies = request.cookies.getAll(); request.cookies.has('nextjs'); request.cookies.delete('nextjs'); const response = NextResponse.next(); response.cookies.set('vercel', 'fast'); response.cookies.set({ name: 'vercel', value: 'fast', path: '/' }); cookie = response.cookies.get('vercel'); return response

Give your agent this brain