Files
Zack TannerandGitHub c986bcccf1 fix: preserve cache behavior for PPR fallback shells with root params (#88556)
When generating PPR fallback shells, a cache miss during warmup was
being treated as a dynamic hole, so the warmup render never filled new
cache entries. This caused root‑param fallback shells (e.g.
`/en/blog/[slug]`) to suspend even though root params were already
known.

This change always creates a fresh prerender RDC for warmup and copies
any seed hits into it. The final render then uses the warmed cache, so
fallback shells can reuse populated entries without short‑circuiting. On
the export side, we now choose a seed RDC by matching known params (e.g.
locale) so /en/... fallback shells don’t get seeded with /fr/... data.
(Previously, the RDC seed was "last-write-wins".

Fixes NAR-716
2026-01-21 08:45:07 -08:00

77 lines
1.8 KiB
TypeScript

import { Suspense } from 'react'
import { cookies } from 'next/headers'
async function getLocaleConfig(localeParam: string) {
'use cache'
await new Promise((resolve) => setTimeout(resolve, 800))
return {
locale: localeParam,
translations: {
home: `Home (${localeParam})`,
blog: `Blog (${localeParam})`,
about: `About (${localeParam})`,
},
}
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ locale: string }>
}) {
return (
<html>
<body>
<div id="static-header">Welcome to our Blog Platform</div>
<nav id="static-nav">
<ul>
<li>Home</li>
<li>Blog</li>
<li>About</li>
</ul>
</nav>
<Suspense
fallback={<div id="locale-loading">Loading locale info...</div>}
>
<LocaleInfo params={params} />
</Suspense>
<Suspense fallback={<div id="dynamic-loading">Loading user...</div>}>
<UserInfo />
</Suspense>
{children}
</body>
</html>
)
}
// This component depends on locale, so it's in Suspense
async function LocaleInfo({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params
const config = await getLocaleConfig(locale)
return (
<header id="locale-header">
<span>Locale: {config.locale}</span>
<div id="translations">
{config.translations.home} | {config.translations.blog} |{' '}
{config.translations.about}
</div>
</header>
)
}
async function UserInfo() {
const cookieStore = await cookies()
const user = cookieStore.get('user')?.value || 'anonymous'
return <div id="user-info">Logged in as: {user}</div>
}
export function generateStaticParams() {
return [{ locale: 'en' }, { locale: 'fr' }]
}