I want to understand why setting a placeholder in generateStaticParams works #92771
Replies: 3 comments 10 replies
|
Pre Cache Components, with an empty array from You'd then have to provide a set of params that hit the In a Cache Components, pages can both contain static and dynamic parts, but how does the prerendering step know what's being used in a given page, and that a static shell can be generated? Again, you provide a set of params that Next.js uses to try to generate a static shell, which can be placed on a CDN, while still being able to serve UI that depends on cookies/headers etc. When you by pass with a placeholder item, the build time is unable to discover any API access that would prevent creating a static shell. Of course, even if you provide one parameter, you can still have branches (like the placeholder one) that error during prerendering runtime, but the frameworks main intention is to validate that at least one value can complete. Moreover, we have an upcoming feature called |
This comment was marked as low quality.
This comment was marked as low quality.
|
I think the key distinction is that the placeholder is not what makes the route “lazy cached.” It mainly gives Cache Components a concrete parameter value to use during the build-time prerender/validation pass. With The important part is that So in your case, something like: export async function generateStaticParams() {
return [{ slug: ['__placeholder__'] }]
}is effectively giving the compiler a representative route so it can perform its prerender validation. The actual CMS slugs can still be discovered at runtime. The downside of the placeholder is specifically the quality of that validation. Next.js only executes the code paths that are reached with the placeholder value. If your application behaves differently for different real slugs—for example, one type of CMS page calls That's what the documentation means by:
So I wouldn't interpret the warning as “this will break lazy caching.” It's more like: you're intentionally giving up comprehensive build-time coverage in exchange for not having to know every CMS route at build time. And you're right about the runtime-slug argument: without This also explains the behavior you're seeing with There is also a useful related discussion in the Next.js repo showing that returning at least one value can change Cache Components behavior in ways that feel somewhat surprising: I'd therefore describe the placeholder as a workaround for the current build-time validation requirement, not as a magic switch for lazy caching. If your CMS route is intentionally “any slug can exist,” and you have tests/validation around the different CMS page types, the trade-off can be reasonable. But I would keep an eye on this behavior as Cache Components evolves, because relying on the placeholder specifically to bypass the empty-params restriction is not the same thing as Next.js officially guaranteeing that placeholder values are semantically meaningful. |


Uh oh!
There was an error while loading. Please reload this page.
https://nextjs.org/docs/messages/empty-generate-static-params#option-2-use-a-placeholder-param, this solution absolutely solves all my troubled with cacheComponents, but it states it should be avoided. Found this at #85807 (comment)
So I want to ask; why does this work at the first place?
With this, I can skip the
<Suspsense>around my{ slug } = await params(got only a[...slug]segment in my sites, it renders all CMS pages of all types, so I need it always).With this, I can see
.next/server/appfill up with.htmland.metafiles for all my pages. So this is actually what I want. All routes that get hit are hard cached when visited. Perfect.So why do I need this placeholder "hack" in the first place? Why doesn't it work without this?
And I don't understand the downsides. "minimal build-time validation and increases the risk of runtime errors for actual parameter values". Validation of what? What actual parameter values, slugs? Without a
generateStaticParams(I don't want to prebuild my entire site on build, I want it to cache lazy) I also risk runtime slugs right?All reactions