Files
Hendrik LiebauandGitHub dbbda2fea3 [Cache Components] Fix caching in generateMetadata/generateViewport (#84228)
When using `'use cache'` in `generateMetadata` or `generateViewport`,
the caching did not work correctly, because we didn't apply the same
special handling for the `params` and `searchParams` props that we do
for layout and page components. This caused the following issues:

- `generateMetadata`/`generateViewport` for a page without params, or
with static params, yielded cache misses when resuming
- `generateMetadata` for a page/layout with unused params, became
dynamic when prerendering a fallback shell
- `generateMetadata` for a page with used search params, produced a
timeout error during prerendering
- `generateViewport` for a page/layout with unused params, produced a
build error (unless opting into fully dynamic rendering)

Still to be done in a follow-up: Omit unused `params` from cache keys,
and upgrade cache keys when they are used, to avoid unnecessary cache
misses when resuming.

closes NAR-321
2025-10-02 17:33:11 +02:00

37 lines
898 B
TypeScript

import { Metadata, ResolvingMetadata } from 'next'
import { connection } from 'next/server'
import { Suspense } from 'react'
export async function generateMetadata(
_: { searchParams: Promise<Record<string, string | string[] | undefined>> },
parent: ResolvingMetadata
): Promise<Metadata> {
'use cache'
// Explicitly not reading search params here. The search params should be
// omitted from the cache key, so that we ensure a cache hit when resuming the
// partially prerendered page.
const { metadataBase } = await parent
return {
title: new Date().toISOString(),
metadataBase: metadataBase?.replace('/bar', '/baz'),
alternates: { canonical: '/qux' },
}
}
export default function Page() {
return (
<Suspense fallback={<p>Loading...</p>}>
<Dynamic />
</Suspense>
)
}
async function Dynamic() {
await connection()
return <p>Dynamic</p>
}