Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
fd7612a
docs: add Getting Started > Building guide
aurorascharff Apr 8, 2026
831b82f
docs: fix build output symbols and improve error explanation
aurorascharff Apr 8, 2026
5647664
docs: add partialFallbacks section for high-cardinality routes
aurorascharff Apr 8, 2026
78b6afb
docs: link to blocking-route error reference instead of inline list
aurorascharff Apr 8, 2026
6f68674
docs: clarify params error requires missing generateStaticParams
aurorascharff Apr 8, 2026
671c577
docs: tighten Step 3 prerender error section
aurorascharff Apr 8, 2026
5009157
docs: link Suspense references to streaming guide
aurorascharff Apr 8, 2026
0eeecff
docs: clarify generateStaticParams doesn't guarantee fully static
aurorascharff Apr 8, 2026
f0d6085
docs: fix generateStaticParams output, routes stay PPR
aurorascharff Apr 8, 2026
200846f
docs: clarify prerender behavior depends on route content
aurorascharff Apr 8, 2026
c4e4164
docs: clarify PPR symbol persists even when fully cached
aurorascharff Apr 8, 2026
9efedb1
docs: simplify generateStaticParams result explanation
aurorascharff Apr 8, 2026
a8094bf
docs: fix unknown params have no shell without partialFallbacks
aurorascharff Apr 8, 2026
809bcc1
docs: clean up generateStaticParams result paragraphs
aurorascharff Apr 8, 2026
82fe8c1
docs: params are resolved ahead of time, not fully prerendered
aurorascharff Apr 8, 2026
1f4b084
docs: unlisted params resolve without a fallback
aurorascharff Apr 8, 2026
a3a5b83
docs: move building guide from getting-started to guides
aurorascharff Apr 8, 2026
0de0823
docs: link first Suspense mention to React docs, second to streaming …
aurorascharff Apr 8, 2026
07b22be
docs: mention loading.js alongside Suspense as fix
aurorascharff Apr 8, 2026
48e8e66
docs: add --debug-build-paths section for building specific routes
aurorascharff Apr 8, 2026
1ab0a5a
docs: add 'What next build does' overview section
aurorascharff Apr 8, 2026
5fe50e6
docs: replace inline fix list with link to blocking-route reference
aurorascharff Apr 8, 2026
b63af2d
docs: add starter code snippet to Example section
aurorascharff Apr 8, 2026
3dba9f1
docs: add related frontmatter and match guide format
aurorascharff Apr 8, 2026
f9f21e8
docs: remove starter snippet that would fail at build time
aurorascharff Apr 8, 2026
7eccc7b
docs: restructure guide to start with the problem
aurorascharff Apr 8, 2026
ae2672d
docs: move Cache Components explanation before the example
aurorascharff Apr 8, 2026
b462a91
docs: remove forward reference to partialFallbacks
aurorascharff Apr 8, 2026
8f14e1d
docs: add cross-references to building guide
aurorascharff Apr 8, 2026
928d1f4
docs: link to building guide from deploying page
aurorascharff Apr 8, 2026
e843778
docs: restore original build output link in caching page
aurorascharff Apr 8, 2026
ad51e62
docs: add build and deploy mention to installation page
aurorascharff Apr 8, 2026
706a4d1
docs: move building guide link after the example block
aurorascharff Apr 8, 2026
22776ad
Update
aurorascharff Apr 8, 2026
9e49f38
Update for new build output
aurorascharff Apr 8, 2026
fe14199
Update
aurorascharff Apr 8, 2026
abb7a32
Update
aurorascharff Apr 8, 2026
707e936
Update
aurorascharff Apr 8, 2026
2498a25
Update writing style
aurorascharff Apr 8, 2026
a241b7a
Restructure guide
aurorascharff Apr 8, 2026
0a76393
Update
aurorascharff Apr 8, 2026
155c741
Update
aurorascharff Apr 8, 2026
cc34f9c
Update docs/01-app/02-guides/building.mdx
aurorascharff Apr 8, 2026
8e3e965
docs: align Building guide route tree with actual next build output
aurorascharff Apr 9, 2026
4047972
docs: refine Building guide (style, switchers, default-first flow)
aurorascharff Apr 9, 2026
e42357a
docs: clarify Building guide route tree explanation
aurorascharff Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions docs/01-app/01-getting-started/17-building.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
title: Building your application
description: Learn what happens when you run next build, how to read the build output, and how to fix common prerender errors.
nav_title: Building
---

When your application is ready for production, `next build` compiles it into optimized bundles and prerendered pages. The build output shows how each route will be served: fully static or partially prerendered.

This guide will show you how to read the build output, pre-render dynamic routes, and fix common build errors.

## Example

As an example, we'll work with a product catalog that has a list page and dynamic product detail pages.

We'll start by reading the build output, then pre-render specific product pages with `generateStaticParams`, and finally fix a prerender error using `--debug-prerender`.

### Step 1: Read the build output

Run `next build` to create a production build. The terminal shows a route table:

```bash filename="Terminal"
Route (app)
┌ ○ /
├ ○ /_not-found
└ ◐ /products/[id]

○ (Static) prerendered as static content
◐ (Partial Prerender) prerendered as static HTML with dynamic server-streamed content
```

Each symbol tells you how a route is served:

| Symbol | Name | Behavior |
| ------ | ----------------- | ------------------------------------------------------------------------- |
| `○` | Static | Fully prerendered at build time. Served from CDN with no server work. |
| `◐` | Partial Prerender | Static shell served from CDN. Dynamic content streams in at request time. |

With [Cache Components](/docs/app/api-reference/config/next-config-js/cacheComponents), every route is either fully static (`○`) or partially prerendered (`◐`). A route shows `◐` when it contains both prerenderable content (static components, [cache components](/docs/app/getting-started/caching)) and dynamic content (components inside [`<Suspense>`](https://react.dev/reference/react/Suspense) that access [runtime APIs](/docs/app/getting-started/caching#working-with-runtime-apis)). The static parts are served instantly from a CDN. The dynamic parts stream in at request time.

> **Good to know:** [Partial Prerendering](/docs/app/getting-started/caching#how-rendering-works) is the default rendering model with Cache Components. You don't need to enable it separately. If a route has Revalidate and Expire columns, see [Time-based revalidation](/docs/app/getting-started/revalidating#time).

### Step 2: Pre-render dynamic routes

Dynamic routes like `/products/[id]` appear in the build output without expanded params. Without knowing which `id` values exist, Next.js can only render them on demand when a user visits.

To pre-render specific params at build time, export [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params):

```tsx filename="app/products/[id]/page.tsx"
export async function generateStaticParams() {
const products = await db.product.findMany()
return products.map((product) => ({ id: product.id }))
}

export default async function Page({ params }) {
const { id } = await params
// ...
}
```

If we run `next build` again, the pre-rendered params appear in the output:

```bash filename="Terminal"
Route (app)
┌ ○ /_not-found
├ ○ /products
├ ◐ /products/[id]
├ ├ /products/1
├ ├ /products/2
├ └ /products/3
```

These pages are now prerendered. Visiting `/products/1` serves the page instantly from CDN without any server work.

Params not listed in `generateStaticParams` (for example, `/products/99`) are rendered on the first request, then cached for subsequent visits.

> **Good to know:** `generateStaticParams` must return at least one param. An empty array causes a [build error](/docs/messages/empty-generate-static-params).

### Step 3: Fix prerender errors

During `next build`, you may see this error:

```txt filename="Terminal"
Uncached data, `params`, `searchParams`, or `connection()` was accessed outside of `<Suspense>`.
This delays the entire page from rendering, resulting in a slow user experience.
```

This happens when a component accesses runtime data without a parent `<Suspense>` boundary. Without one, the page can't send any HTML until the data resolves, which blocks the entire response. Common triggers:

- Awaiting [`params`](/docs/app/api-reference/file-conventions/page#params-optional) or [`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional) directly in a Page or Layout
- Calling [`cookies()`](/docs/app/api-reference/functions/cookies) or [`headers()`](/docs/app/api-reference/functions/headers)
- Calling [`connection()`](/docs/app/api-reference/functions/connection)
- Fetching data that isn't cached with [`'use cache'`](/docs/app/api-reference/directives/use-cache)

For example, `await params` directly in a Page blocks the entire page from prerendering:

```tsx filename="app/products/[id]/page.tsx"
export default async function Page({ params }) {
const { id } = await params
const product = await db.product.find(id)
return <div>{product.name}</div>
}
```

To fix this, move the data access into a child component wrapped in [`<Suspense>`](https://react.dev/reference/react/Suspense):

```tsx filename="app/products/[id]/page.tsx"
import { Suspense } from 'react'

export default function Page({ params }) {
return (
<Suspense fallback={<ProductSkeleton />}>
<ProductContent params={params} />
</Suspense>
)
}

async function ProductContent({ params }) {
const { id } = await params
const product = await db.product.find(id)
return <div>{product.name}</div>
}
```

The `<Suspense>` fallback is prerendered into the static shell. The content streams in at request time. If we run `next build` again, the error is gone and the route shows as `◐` (Partial Prerender).

Other ways to resolve this error:

- **Cache the component** with [`'use cache'`](/docs/app/api-reference/directives/use-cache) so its output can be prerendered.
- **Add [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params)** to provide sample params at build time. Routes with known params can be fully prerendered.
- **Add a [`loading.js`](/docs/app/api-reference/file-conventions/loading)** file to create a route-level Suspense boundary.

See the [blocking-route error reference](/docs/messages/blocking-route) for more details.

#### Getting detailed stack traces

When the error doesn't point to the exact line, use `--debug-prerender`:

```bash filename="Terminal"
next build --debug-prerender
```

This disables minification and enables source maps for server bundles, producing readable stack traces that show which function triggered the error. It also continues past the first error so you can see all issues at once.

> **Warning:** Do not deploy builds generated with `--debug-prerender`. It disables optimizations needed for production performance.

## Next steps

You now know how to read the build output, pre-render dynamic routes, and fix prerender errors.

Next, learn how to:

- [Deploy your application](/docs/app/getting-started/deploying)
- [Cache data and UI](/docs/app/getting-started/caching)
- [Build public, static pages](/docs/app/guides/public-static-pages)
Loading