-
Notifications
You must be signed in to change notification settings - Fork 30.8k
docs: add Building guide #92507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
aurorascharff
wants to merge
46
commits into
canary
Choose a base branch
from
docs/getting-started-building
base: canary
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+245
−1
Draft
docs: add Building guide #92507
Changes from 42 commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
fd7612a
docs: add Getting Started > Building guide
aurorascharff 831b82f
docs: fix build output symbols and improve error explanation
aurorascharff 5647664
docs: add partialFallbacks section for high-cardinality routes
aurorascharff 78b6afb
docs: link to blocking-route error reference instead of inline list
aurorascharff 6f68674
docs: clarify params error requires missing generateStaticParams
aurorascharff 671c577
docs: tighten Step 3 prerender error section
aurorascharff 5009157
docs: link Suspense references to streaming guide
aurorascharff 0eeecff
docs: clarify generateStaticParams doesn't guarantee fully static
aurorascharff f0d6085
docs: fix generateStaticParams output, routes stay PPR
aurorascharff 200846f
docs: clarify prerender behavior depends on route content
aurorascharff c4e4164
docs: clarify PPR symbol persists even when fully cached
aurorascharff 9efedb1
docs: simplify generateStaticParams result explanation
aurorascharff a8094bf
docs: fix unknown params have no shell without partialFallbacks
aurorascharff 809bcc1
docs: clean up generateStaticParams result paragraphs
aurorascharff 82fe8c1
docs: params are resolved ahead of time, not fully prerendered
aurorascharff 1f4b084
docs: unlisted params resolve without a fallback
aurorascharff a3a5b83
docs: move building guide from getting-started to guides
aurorascharff 0de0823
docs: link first Suspense mention to React docs, second to streaming …
aurorascharff 07b22be
docs: mention loading.js alongside Suspense as fix
aurorascharff 48e8e66
docs: add --debug-build-paths section for building specific routes
aurorascharff 1ab0a5a
docs: add 'What next build does' overview section
aurorascharff 5fe50e6
docs: replace inline fix list with link to blocking-route reference
aurorascharff b63af2d
docs: add starter code snippet to Example section
aurorascharff 3dba9f1
docs: add related frontmatter and match guide format
aurorascharff f9f21e8
docs: remove starter snippet that would fail at build time
aurorascharff 7eccc7b
docs: restructure guide to start with the problem
aurorascharff ae2672d
docs: move Cache Components explanation before the example
aurorascharff b462a91
docs: remove forward reference to partialFallbacks
aurorascharff 8f14e1d
docs: add cross-references to building guide
aurorascharff 928d1f4
docs: link to building guide from deploying page
aurorascharff e843778
docs: restore original build output link in caching page
aurorascharff ad51e62
docs: add build and deploy mention to installation page
aurorascharff 706a4d1
docs: move building guide link after the example block
aurorascharff 22776ad
Update
aurorascharff 9e49f38
Update for new build output
aurorascharff fe14199
Update
aurorascharff abb7a32
Update
aurorascharff 707e936
Update
aurorascharff 2498a25
Update writing style
aurorascharff a241b7a
Restructure guide
aurorascharff 0a76393
Update
aurorascharff 155c741
Update
aurorascharff cc34f9c
Update docs/01-app/02-guides/building.mdx
aurorascharff 8e3e965
docs: align Building guide route tree with actual next build output
aurorascharff 4047972
docs: refine Building guide (style, switchers, default-first flow)
aurorascharff e42357a
docs: clarify Building guide route tree explanation
aurorascharff File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| --- | ||
| 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 | ||
| related: | ||
| description: Related API references and guides. | ||
| links: | ||
| - app/api-reference/cli/next | ||
| - app/api-reference/functions/generate-static-params | ||
| - app/api-reference/config/next-config-js/cacheComponents | ||
| - app/guides/streaming | ||
| - app/guides/public-static-pages | ||
| - app/guides/ci-build-caching | ||
| --- | ||
|
|
||
| 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 covers how to read the build output, pre-render dynamic routes, and fix common build errors. | ||
|
|
||
| ## What `next build` does | ||
|
|
||
| Running `next build` goes through these phases: | ||
|
|
||
| 1. **Setup.** Loads [environment variables](/docs/app/guides/environment-variables) (`.env` files), validates your [`next.config`](/docs/app/api-reference/config/next-config-js), and generates a [build ID](/docs/app/api-reference/config/next-config-js/generateBuildId). | ||
| 2. **Route discovery.** Scans `app/` and `pages/` directories for routes, middleware, and [instrumentation](/docs/app/api-reference/file-conventions/instrumentation) hooks. Generates TypeScript route definitions. | ||
aurorascharff marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 3. **Compilation.** Bundles client, server, and edge code with [Turbopack](/docs/app/api-reference/turbopack) (or Webpack). Transpiles TypeScript and JSX, tree-shakes unused code, and optimizes CSS and fonts. Type checking runs in parallel. | ||
| 4. **Static analysis.** Classifies each route as static or partially prerendered. Collects [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params) output. Checks for [prerender-blocking errors](/docs/messages/blocking-route). | ||
| 5. **Prerendering.** Prerenders static pages and PPR shells to HTML. Generates [RSC payloads](/docs/app/getting-started/server-and-client-components#on-the-server) for client-side navigation. | ||
| 6. **Output.** Writes the final build to `.next/`. For [`output: 'standalone'`](/docs/app/guides/self-hosting), bundles only the files needed at runtime. For [`output: 'export'`](/docs/app/guides/static-exports), generates a full static site. Prints the route table. | ||
|
|
||
| ## Reading the build output | ||
|
|
||
| With [Cache Components](/docs/app/api-reference/config/next-config-js/cacheComponents), Next.js prerenders as much of each route as possible at build time. Components that depend on request-time data (such as `params`, `searchParams`, `cookies()`, or `headers()`) cannot be resolved ahead of time. You need to explicitly handle these with [`<Suspense>`](/docs/app/guides/streaming) or [`'use cache'`](/docs/app/api-reference/directives/use-cache), otherwise the build fails with a [prerender-blocking error](/docs/messages/blocking-route). | ||
|
|
||
| After a successful build, the route table shows a symbol next to each route: | ||
aurorascharff marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| | 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. | | ||
| | `ƒ` | Dynamic | Server-rendered on demand for every request. | | ||
|
|
||
| With [Cache Components](/docs/app/api-reference/config/next-config-js/cacheComponents), pages are always `○` or `◐`. The `ƒ` symbol appears for API routes, [Proxy](/docs/app/api-reference/file-conventions/proxy) routes, dynamic [metadata](/docs/app/api-reference/functions/generate-metadata) (such as `icon` or `opengraph-image`), and projects without Cache Components. | ||
|
|
||
| [Partial Prerendering](/docs/app/getting-started/caching#how-rendering-works) is the default rendering model. For dynamic routes with [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params), each listed param shows its own symbol: `○` if the page is fully static, or `◐` if it contains streamed content. | ||
|
|
||
| ## Example | ||
|
|
||
| We have a dynamic product detail page at `/products/[id]` that fetches product data: | ||
|
|
||
| ```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> | ||
| } | ||
| ``` | ||
|
|
||
| Running `next build` fails: | ||
|
|
||
| ```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. | ||
| ``` | ||
|
|
||
| The param values are unknown at build time, so Next.js cannot prerender the page. You need to tell it how to handle the dynamic data. See the [blocking-route error reference](/docs/messages/blocking-route) for a full list of triggers and fixes. | ||
|
|
||
| ### Resolve params with `generateStaticParams` | ||
|
|
||
| The most direct fix is telling Next.js which param values exist. Export [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params) to resolve them at build time: | ||
|
|
||
| ```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 | ||
| const product = await db.product.find(id) | ||
| return <div>{product.name}</div> | ||
| } | ||
| ``` | ||
|
|
||
| Now `next build` succeeds: | ||
|
|
||
| ```bash filename="Terminal" | ||
| Route (app) | ||
| ┌ ○ / | ||
| ├ ○ /_not-found | ||
| ├ /products/[id] | ||
| │ ├ ○ /products/1 | ||
| │ ├ ○ /products/2 | ||
| │ └ ○ [+4 more paths] | ||
|
|
||
| ○ (Static) prerendered as static content | ||
| ◐ (Partial Prerender) prerendered as static HTML with dynamic server-streamed content | ||
| ``` | ||
|
|
||
| Unlisted params (for example, `/products/99`) are server-rendered on the first request and the page has to resolve entirely without a fallback. After the first visit, the result is cached. | ||
|
|
||
| > **Good to know:** `generateStaticParams` must return at least one param. An empty array causes a [build error](/docs/messages/empty-generate-static-params). | ||
|
|
||
| Routes that use [`cacheLife`](/docs/app/api-reference/functions/cacheLife) also show `Revalidate` and `Expire` columns: | ||
|
|
||
| ```bash filename="Terminal" | ||
| Route (app) Revalidate Expire | ||
| ┌ ○ / 15m 1y | ||
| ├ ○ /_not-found | ||
| ├ /products/[id] | ||
| │ ├ ○ /products/1 15m 1y | ||
| │ ├ ○ /products/2 15m 1y | ||
| │ └ ○ [+4 more paths] | ||
| ``` | ||
|
|
||
| ### Stream dynamic content with Suspense | ||
|
|
||
| You may not have all param values ahead of time, or the page may have content that depends on the request (cookies, headers). In these cases, [stream](/docs/app/guides/streaming) the dynamic content with [`<Suspense>`](https://react.dev/reference/react/Suspense), or add a [`loading.js`](/docs/app/api-reference/file-conventions/loading) file: | ||
|
|
||
| ```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 }) { | ||
aurorascharff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const { id } = await params | ||
| const product = await db.product.find(id) | ||
| return <div>{product.name}</div> | ||
| } | ||
| ``` | ||
|
|
||
| The fallback is prerendered into the static shell. The content streams in at request time: | ||
|
|
||
| ```bash filename="Terminal" | ||
| Route (app) | ||
| ┌ ○ / | ||
| ├ ○ /_not-found | ||
| ├ ◐ /products/[id] | ||
| │ └ ◐ /products/[id] | ||
| ``` | ||
|
|
||
| You can combine both approaches: use `generateStaticParams` for known params and `<Suspense>` for dynamic content within the page. | ||
|
|
||
| ### High-cardinality routes | ||
|
|
||
| For sites with many possible slugs (e-commerce with millions of products, user-generated content), pre-rendering every page at build time is not practical. | ||
|
|
||
| The experimental [`partialFallbacks`](/docs/app/api-reference/config/next-config-js/partialFallbacks) flag serves an instant `<Suspense>` shell from CDN for unknown slugs while the dynamic data streams in. After the first visit, the page is cached and upgraded to a fully static version. | ||
aurorascharff marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```ts filename="next.config.ts" | ||
| import type { NextConfig } from 'next' | ||
|
|
||
| const nextConfig: NextConfig = { | ||
| cacheComponents: true, | ||
| experimental: { | ||
| partialFallbacks: true, | ||
| }, | ||
| } | ||
|
|
||
| export default nextConfig | ||
aurorascharff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| Without `partialFallbacks`, unlisted params block until the server finishes rendering. With `partialFallbacks`, you can keep `generateStaticParams` small and let traffic determine which additional pages get cached. | ||
|
|
||
| ## Debugging prerender errors | ||
|
|
||
| If the error does not 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. | ||
|
|
||
aurorascharff marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ### Building specific routes | ||
|
|
||
| In large applications, you can build only specific routes using `--debug-build-paths` to speed up debugging: | ||
|
|
||
| ```bash filename="Terminal" | ||
| next build --debug-build-paths="app/products/[id]/page.tsx" | ||
| ``` | ||
|
|
||
| This accepts comma-separated file paths and glob patterns. See [`--debug-build-paths`](/docs/app/api-reference/cli/next#building-specific-routes) for more details. | ||
|
|
||
| ## Next steps | ||
|
|
||
| Next, learn how to: | ||
|
|
||
| - [Deploy your application](/docs/app/getting-started/deploying) | ||
| - [Cache data and UI](/docs/app/getting-started/caching) | ||
| - [Configure CI build caching](/docs/app/guides/ci-build-caching) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.