mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
c2b4c0815c
This PRs unifies the caching story across the docs, making Cache Components the happy path, while still providing guidance to users in the old model. However, instead of explaining the old model and its caching layers, we've created a new guide focusing on what APIs to use and when. This follow-up PR aligns terminology across the docs: https://github.com/vercel/next.js/pull/90589 ## IA updates Getting Started section: - Improves Getting Started progression: - **Before:** CC → Fetching Data → Updating Data → Caching and Revalidating (old and new model mixed) - **After:** Fetching Data (Dynamic) → Mutating Data (Dynamic) → Caching with CC (Prerendering) → Revalidating with CC. - New: `caching.mdx` (CC-first) - Structure: - Enabling Cache Components - Data vs UI-level caching - Working with request time APIs - Passing request values to cached functions - Working with non-deterministic operations - Working with synchronous operations - How rendering works (PPR and static shell story) - New: `revalidating.mdx` (CC-first) - Explains how to use `cacheLife` and `cacheTag` Guides Section: - New: `caching-and-revalidating.mdx` (Previous Model) - For users who are not using CC, includes `fetch` options and route segment config - Moves route segment config options that don't apply to CC from API reference to this guide (for easy archiving in the future). - New: `migrating-to-cache-components.mdx` (WIP) - Del: `caching.mdx` 😌 ## Terminology We should remove caching layers from the docs. Users only needed to be exposed to them when they were configured independently, but the new CC APIs work across layers. To make it easier to review this PR, I'm consolidating terminology and fixing broken links in a new PR: https://github.com/vercel/next.js/pull/90589 --------- Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
79 lines
3.2 KiB
Plaintext
79 lines
3.2 KiB
Plaintext
---
|
|
title: Empty generateStaticParams with Cache Components
|
|
---
|
|
|
|
## Why This Error Occurred
|
|
|
|
You're using [Cache Components](https://nextjs.org/docs/app/getting-started/caching) in your Next.js application, and one of your `generateStaticParams` functions returned an empty array, which causes a build error.
|
|
|
|
When Cache Components is enabled, Next.js performs build-time validation to ensure your routes can be properly prerendered without runtime dynamic access errors. If `generateStaticParams` returns an empty array, Next.js cannot validate that your route won't access dynamic values (like `await cookies()`, `await headers()`, or `await searchParams`) at runtime, which would cause errors.
|
|
|
|
This strict requirement ensures:
|
|
|
|
- Build-time validation catches potential runtime errors early
|
|
- All routes using Cache Components have at least one static variant to validate against
|
|
- You don't accidentally deploy routes that will fail at runtime
|
|
|
|
## Possible Ways to Fix It
|
|
|
|
### Option 1: Return at least one static param
|
|
|
|
Modify your `generateStaticParams` function to return at least one set of parameters. This is the most common fix and allows build-time validation to work properly.
|
|
|
|
```tsx filename="app/blog/[slug]/page.tsx"
|
|
// This will cause an error with Cache Components
|
|
export async function generateStaticParams() {
|
|
return [] // Empty array not allowed
|
|
}
|
|
|
|
// Return at least one sample param
|
|
export async function generateStaticParams() {
|
|
return [{ slug: 'hello-world' }, { slug: 'getting-started' }]
|
|
}
|
|
```
|
|
|
|
These samples serve dual purposes:
|
|
|
|
1. **Build-time validation**: Verify your route structure is safe
|
|
2. **Prerendering**: Generate instant-loading pages for popular routes
|
|
|
|
The build process only validates code paths that execute with your sample params. If runtime parameters trigger conditional logic that renders branches accessing runtime APIs (like `cookies()`) without Suspense, or dynamic content without Suspense or `use cache`, those will cause runtime errors.
|
|
|
|
### Option 2: Use a placeholder param
|
|
|
|
If you don't know actual values at build time, you can use a placeholder for validation. However, this defeats the purpose of build-time validation and should be avoided:
|
|
|
|
```tsx filename="app/blog/[slug]/page.tsx"
|
|
export async function generateStaticParams() {
|
|
// Placeholder only validates one code path
|
|
return [{ slug: '__placeholder__' }]
|
|
}
|
|
|
|
export default async function Page({
|
|
params,
|
|
}: {
|
|
params: Promise<{ slug: string }>
|
|
}) {
|
|
const { slug } = await params
|
|
|
|
// Handle placeholder case
|
|
if (slug === '__placeholder__') {
|
|
notFound()
|
|
}
|
|
|
|
// Real params may trigger code paths
|
|
// that access dynamic APIs incorrectly, causing
|
|
// runtime errors that cannot be caught by error boundaries
|
|
const post = await getPost(slug)
|
|
return <div>{post.title}</div>
|
|
}
|
|
```
|
|
|
|
Using placeholders provides minimal build-time validation and increases the risk of runtime errors for actual parameter values.
|
|
|
|
## Useful Links
|
|
|
|
- [Cache Components Documentation](https://nextjs.org/docs/app/getting-started/caching)
|
|
- [generateStaticParams API Reference](https://nextjs.org/docs/app/api-reference/functions/generate-static-params)
|
|
- [Dynamic Routes with Cache Components](/docs/app/api-reference/file-conventions/dynamic-routes#with-cache-components)
|