Architecture Overview
Server Runtime
Rendering Pipeline
Client Navigation
Caching and Export
Development Tools
Build and Configuration
Ecosystem Packages
Testing Infrastructure
How It Works
The following files were used as context for generating this wiki page:
Static Export is a core Next.js build subsystem responsible for translating an application's compiled build artifacts into fully pre-rendered static assets, HTML pages, Server Components payloads (.rsc), and data files (.json) that can be hosted directly on any static web server or CDN without needing a running Node.js server. When configured with output: export or executed via export routines, Next.js shifts route processing completely to build time, transforming dynamic page routes, app directory layout paths, and API handlers into deterministic file trees.
The subsystem bridges the gap between server-side rendering pipelines and static file distribution by leveraging production manifests (pages-manifest.json, app-path-routes-manifest.json, prerender-manifest.json), mocking HTTP requests and responses, and executing rendering workers. It enforces strict structural rules, rejecting incompatible server APIs like getServerSideProps or unoptimized image loaders, and serializes page outputs via utility writers into precise filesystem hierarchies.
The static export process initializes inside exportAppImpl, orchestrating environment setup, manifest loading, output directory clearance, and route dispatching. Before any page compilation occurs, the subsystem loads the user configuration using PHASE_EXPORT, verifies the existence of the production BUILD_ID file, and parses manifests to discover available pages and app routes.
If the BUILD_ID file is missing inside the distribution directory, an ExportError is thrown, halting the export pipeline to prevent silent failures. Custom configurations and custom routes are audited; if custom headers, rewrites, or redirects are detected outside of Next.js hosting support, warnings are logged.
Note
The public and static directories at the project root are reserved in Next.js and cannot be used as the export output directory (outDir), triggering an immediate ExportError if attempted.
Once initialization completes, routes are dispatched to exportPageImpl within the worker subsystem. Each route is normalized based on its directory origin (app/ or pages/), locale configuration, and dynamic parameters. Mock HTTP request and response objects are generated via createRequestResponseMocks to simulate runtime execution context.
The worker determines filename structures depending on whether subFolders (trailing slashes) are configured, formatting paths as either ${p}/index.html or ${p}.html. For app/ routes, the subsystem handles both page components and App Route handlers (route.ts), extracting blobs, response headers, status codes, and writing accompanying .body and .meta files.
Sources: packages/next/src/export/worker.ts:201-245, packages/next/src/export/routes/app-route.ts:36-174
Warning
Dynamic App Router pages with unknown parameters or missing static generation parameters will fail static export unless wrapped with proper fallback handling or explicit static generation configuration.
The static export subsystem bifurcates handling depending on whether a route originates from the legacy pages/ directory or the modern app/ directory.
Sources: packages/next/src/export/routes/pages.ts:29-57, packages/next/src/export/routes/app-page.ts:40-88
exportPagesPage): Renders page components, checks for forbidden hooks like getServerSideProps (which throws SERVER_PROPS_EXPORT_ERROR), and writes associated .json data files into the pages data directory using NEXT_DATA_SUFFIX.exportAppPage): Executes lazyRenderAppPage, handling React Server Component (.rsc) payloads, parallel route segments, prefetch hints, and segment data files (.rsc_segments/).Sources: packages/next/src/export/routes/pages.ts:73-137, packages/next/src/export/routes/app-page.ts:95-182
Sources: packages/next/src/shared/lib/constants.ts:32-68, packages/next/src/export/routes/pages.ts:48-56, packages/next/src/export/routes/app-page.ts:107-162
Next.js manages custom export targets through hasCustomExportOutput, detecting when output: export is configured in next.config.js. When this mode is active, next build automatically triggers the export phase, mapping the user-configured distribution directory to act as the final output destination while keeping temporary manifests inside .next.
export function hasCustomExportOutput(config: NextConfigComplete) {
return config.output === 'export' && config.distDir !== '.next'
}The CLI build harness (nextBuild) initializes build execution flags, manages memory debugging modes via enableMemoryDebuggingMode and disableMemoryDebuggingMode, and captures CPU profiles upon receiving termination signals (SIGTERM, SIGINT).
Static export enforces rigid boundaries against runtime dynamic data access. When a route attempts to access uncacheable data sources, request metadata, or dynamic APIs (such as cookies(), headers(), or uncached fetch()) outside of a <Suspense> boundary during static generation, the render engine throws static generation bailout errors.
Sources: packages/next/src/server/app-render/app-render.tsx:7378-7384, packages/next/src/server/render.tsx:578-614
These bailouts trigger specific error messages defined in errors.json:
dynamic = "error" or standard static generation encounters dynamic runtime usage without caching or fallback generation.next start or images.unoptimized = true in next.config.js.Sources: packages/next/errors.json:554-612, packages/next/src/server/app-render/blocking-route-messages.ts:1-27
Caution
Utilizing getServerSideProps or unoptimized default image loaders will immediately abort the static export process with fatal build errors.
Post-export analysis can be performed using the internal static routes CLI (staticRoutesInfoCli). This utility parses built artifacts statically without executing the application code, partitioning per-route file footprints into six distinct categories:
clientJs: Client-side JavaScript bundles.clientCss: Client stylesheet assets.clientMaps: Client-side source maps.serverBundled: Bundled server code artifacts.serverUnbundled: Unbundled server dependencies.serverMaps: Server-side source maps.Concurrently, build metrics and feature usage are recorded via telemetry events (eventBuildCompleted, eventBuildOptimize, and eventBuildFeatureUsage) to track static page ratios, bundler usage (Webpack, Turbopack, or Rspack), and experimental feature adoption.