ISR with cacheComponents but without partialPrefetching #98177
|
With this pattern, ISR works if partialPrefetching is enabled, but not if it's disabled: export async function generateStaticParams() {
return [{ slug: 'a' }]
}
export default async function Page(props: PageProps<'/[slug]'>) {
console.log('rendering')
return (
<Suspense fallback={<div>Loading...</div>}>
<PageInner {...props} />
</Suspense>
)
}
async function PageInner(props: PageProps<'/[slug]'>) {
const { slug } = await props.params
return <h1>Page {slug}</h1>
}This can be verified by Is this a bug, or is it just unclear documentation? There's nothing at https://nextjs.org/docs/app/guides/migrating-to-cache-components#await-params-inside-suspense or https://nextjs.org/docs/app/api-reference/file-conventions/dynamic-routes#with-cache-components to warn me that ISR won't work without PPF. https://nextjs.org/docs/app/guides/incremental-static-regeneration-cache-components only covers the behaviour with PPF enabled. For ISR to work with PPR disabled it seems we need to remove the Suspense and add Tested on 16.3.4 and 16.4.0-canary.13 |
Replies: 2 comments
|
In the repository, with only cacheComponents enabled, IIRC, this route communicates that, it is OK to serve a fallback, or that a fallback UI can be used in place because the What you'd need to do is accept a blocking UI: export default async function Page(props: PageProps<"/posts/[slug]">) {
console.log("rendering Page");
const { slug } = await props.params;
// rest of the appNow there's no good UI we could serve instead, so the framework does a blocking render. That produces a result that can be saved, associated with a URL. It is very rough, though, as your repro shows, moving the params access under a Suspense boundary, disabled it. What was missing was the ability to serve fallback UI, while also rendering a result associated with a URL, to be saved and served to further visitors, that behavior needed more development and testing. In version 16.3 that behavior is available, but because it implies costs for a project, it was put together with the partial prefetching flag, to take advantage of App Shells, and the new new prefetch={true} behavior. You wouldn't want to suddenly see ISR writes costs upon upgrade. I'd admit there's a docs gap though, this section https://nextjs.org/docs/app/api-reference/file-conventions/dynamic-routes#with-generatestaticparams should mention that if there's a fallback that can be used for all params, there won't be any ISR. I thought I had add it, because this can also go wrong if you have a Suspense in a shared layout higher up, wrapping the relevant segment. I wouldn't add in instant false though, it'll prevent other validations from running. |
|
Hey @icyJoseph, I really appreciate how your responses here are always so prompt and helpful - thank you! |
In the repository, with only cacheComponents enabled, IIRC, this route communicates that, it is OK to serve a fallback, or that a fallback UI can be used in place because the
await params, happens from within a Suspense boundary.What you'd need to do is accept a blocking UI:
Now there's no good UI we could serve instead, so the framework does a blocking render. That produces a result that can be saved, associated with a URL.
It is very rough, though, as your repro shows, moving the params access under a Suspense boundary, disa…