---
title: "Static Export"
description: "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 (..."
last_updated: "2026-09-23T10:52:03.199778+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/caching-and-export/static-export"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/next/src/export/index.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts)
- [packages/next/src/export/worker.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/worker.ts)
- [packages/next/src/server/app-render/app-render.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/server/app-render/app-render.tsx)
- [packages/next/src/cli/internal/static-routes-info.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/internal/static-routes-info.ts)
- [packages/next/errors.json](https://github.com/blade47/next.js/blob/main/packages/next/errors.json)
- [packages/next/src/cli/next-build.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-build.ts)
- [packages/next/src/export/utils.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts)
- [packages/next/src/server/lib/router-utils/filesystem.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/lib/router-utils/filesystem.ts)
- [packages/next/src/server/next-server.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/next-server.ts)
- [packages/next/src/export/routes/app-page.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-page.ts)
- [packages/next/src/server/app-render/collect-segment-data.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/server/app-render/collect-segment-data.tsx)
- [packages/next/src/types.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/types.ts)
- [packages/next/src/server/render.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/server/render.tsx)
- [packages/next/src/export/routes/app-route.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-route.ts)
- [packages/next/src/cli/internal/upload-trace.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/internal/upload-trace.ts)
- [packages/next/src/shared/lib/constants.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/shared/lib/constants.ts)
- [packages/next/src/trace/report/to-json-build.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/trace/report/to-json-build.ts)
- [packages/create-next-app/templates/index.ts](https://github.com/blade47/next.js/blob/main/packages/create-next-app/templates/index.ts)
- [packages/next/src/export/routes/pages.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/pages.ts)
- [packages/next/src/telemetry/events/build.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/telemetry/events/build.ts)
- [packages/next/src/trace/trace-uploader.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/trace/trace-uploader.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-lint-to-eslint-cli/legacy-config/package.json](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-lint-to-eslint-cli/flat-config-flat-compat/package.json](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-lint-to-eslint-cli/flat-config-flat-compat-with-other-compat/package.json](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts)
- [packages/next-codemod/transforms/__testfixtures__/next-lint-to-eslint-cli/flat-config/package.json](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts)
- [packages/next/taskfile.js](https://github.com/blade47/next.js/blob/main/packages/next/taskfile.js)
- [packages/next-swc/package.json](https://github.com/blade47/next.js/blob/main/packages/next-swc/package.json)
- [packages/next/src/server/app-render/blocking-route-messages.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/app-render/blocking-route-messages.ts)
- [apps/bundle-analyzer/package.json](https://github.com/blade47/next.js/apps/bundle-analyzer/package.json)
- [Cargo.toml](https://github.com/blade47/next.js/Cargo.toml)
</details>

## Overview

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.

Sources: [packages/next/src/export/index.ts:192-244](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L192-L244)

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.

Sources: [packages/next/src/export/utils.ts:3-14](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts#L3-L14), [packages/next/src/export/index.ts:259-284](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L259-L284)

## Export Lifecycle and Initialization Control Flow

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.

Sources: [packages/next/src/export/index.ts:192-235](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L192-L235)

```mermaid
flowchart TD
    A["exportAppImpl(dir, options)"] --> B["Load dotenv & Next Config<br>(PHASE_EXPORT)"]
    B --> C["Validate BUILD_ID existence<br>in distDir"]
    C --> D["Read pagesManifest & appRoutePathManifest"]
    D --> E["Clear outDir & create<br>_next/[buildId] directory"]
    E --> F["Copy static directories<br>(public & .next/static)"]
    F --> G["Iterate routes and dispatch<br>to worker export pipelines"]
```

Sources: [packages/next/src/export/index.ts:192-375](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L192-L375)

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.

Sources: [packages/next/src/export/index.ts:237-256](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L237-L256)

> [!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.

Sources: [packages/next/src/export/index.ts:334-347](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L334-L347)

## Route Processing Pipeline and Worker Implementation

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.

Sources: [packages/next/src/export/worker.ts:71-167](https://github.com/blade47/next.js/blob/main/packages/next/src/export/worker.ts#L71-L167)

```mermaid
sequenceDiagram
    participant Index as exportAppImpl
    participant Worker as exportPageImpl
    participant RouteMod as App/Pages Module
    participant Writer as MultiFileWriter

    Index->>Worker: Dispatch exportPath & renderOpts
    Worker->>Worker: Create request/response mocks & params
    Worker->>RouteMod: Load components & execute render
    RouteMod-->>Worker: Return HTML, RSC payload, & metadata
    Worker->>Writer: Append file outputs (.html, .rsc, .json)
    Writer-->>Worker: Commit to filesystem
    Worker-->>Index: Return ExportRouteResult
```

Sources: [packages/next/src/export/worker.ts:71-245](https://github.com/blade47/next.js/blob/main/packages/next/src/export/worker.ts#L71-L245)

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](https://github.com/blade47/next.js/blob/main/packages/next/src/export/worker.ts#L201-L245), [packages/next/src/export/routes/app-route.ts:36-174](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-route.ts#L36-L174)

> [!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.

Sources: [packages/next/src/export/index.ts:308-330](https://github.com/blade47/next.js/blob/main/packages/next/src/export/index.ts#L308-L330)

## Pages Directory vs. App Directory Export Handling

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](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/pages.ts#L29-L57), [packages/next/src/export/routes/app-page.ts:40-88](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-page.ts#L40-L88)

- **Pages Directory (`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`.
- **App Directory (`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](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/pages.ts#L73-L137), [packages/next/src/export/routes/app-page.ts:95-182](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-page.ts#L95-L182)

| Directory / Module | Route Type | Output Files Generated | Restrictions & Invariants |
| :--- | :--- | :--- | :--- |
| `pages/` | `PAGES` | `.html`, `._next/data/.../*.json` | `getServerSideProps` prohibited |
| `pages/` | `PAGES_API` | Skipped / Node.js function | API routes not supported in static export |
| `app/` | `APP_PAGE` | `.html`, `.rsc`, `._segments/` | Dynamic data without caching throws bailout |
| `app/` | `APP_ROUTE` | `.body`, `.meta` | Must enable static gen or use caching |

Sources: [packages/next/src/shared/lib/constants.ts:32-68](https://github.com/blade47/next.js/blob/main/packages/next/src/shared/lib/constants.ts#L32-L68), [packages/next/src/export/routes/pages.ts:48-56](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/pages.ts#L48-L56), [packages/next/src/export/routes/app-page.ts:107-162](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/app-page.ts#L107-L162)

## Configuration and Custom Output Resolution

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`.

Sources: [packages/next/src/export/utils.ts:3-14](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts#L3-L14)

```typescript
export function hasCustomExportOutput(config: NextConfigComplete) {
  return config.output === 'export' && config.distDir !== '.next'
}
```

Sources: [packages/next/src/export/utils.ts:3-14](https://github.com/blade47/next.js/blob/main/packages/next/src/export/utils.ts#L3-L14)

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`).

Sources: [packages/next/src/cli/next-build.ts:39-150](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/next-build.ts#L39-L150)

## Error Handling and Static Generation Bailouts

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](https://github.com/blade47/next.js/blob/main/packages/next/src/server/app-render/app-render.tsx#L7378-L7384), [packages/next/src/server/render.tsx:578-614](https://github.com/blade47/next.js/blob/main/packages/next/src/server/render.tsx#L578-L614)

These bailouts trigger specific error messages defined in `errors.json`:

- **Error Code 553 / 558 / 577**: Triggered when a route configured with `dynamic = "error"` or standard static generation encounters dynamic runtime usage without caching or fallback generation.
- **Error Code 603**: Triggered when Image Optimization uses the default loader during export, requiring either `next start` or `images.unoptimized = true` in `next.config.js`.

Sources: [packages/next/errors.json:554-612](https://github.com/blade47/next.js/blob/main/packages/next/errors.json#L554-L612), [packages/next/src/server/app-render/blocking-route-messages.ts:1-27](https://github.com/blade47/next.js/blob/main/packages/next/src/server/app-render/blocking-route-messages.ts#L1-L27)

> [!CAUTION]
> Utilizing `getServerSideProps` or unoptimized default image loaders will immediately abort the static export process with fatal build errors.

Sources: [packages/next/src/export/routes/pages.ts:48-50](https://github.com/blade47/next.js/blob/main/packages/next/src/export/routes/pages.ts#L48-L50), [packages/next/errors.json:604](https://github.com/blade47/next.js/blob/main/packages/next/errors.json#L604)

## Static Routes Analysis and Telemetry Tracking

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:

1. `clientJs`: Client-side JavaScript bundles.
2. `clientCss`: Client stylesheet assets.
3. `clientMaps`: Client-side source maps.
4. `serverBundled`: Bundled server code artifacts.
5. `serverUnbundled`: Unbundled server dependencies.
6. `serverMaps`: Server-side source maps.

Sources: [packages/next/src/cli/internal/static-routes-info.ts:1-70](https://github.com/blade47/next.js/blob/main/packages/next/src/cli/internal/static-routes-info.ts#L1-L70)

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.

Sources: [packages/next/src/telemetry/events/build.ts:76-180](https://github.com/blade47/next.js/blob/main/packages/next/src/telemetry/events/build.ts#L76-L180)

## Related

- [Incremental Cache](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/caching-and-export/incremental-cache)
- [CLI Commands](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/build-and-config/cli-commands)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
