mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
As of #49343, in dev mode only, we accidentally change the `metadataBase` from an `URL` instance to a URL string, when passing it to child layouts or pages via the `parent` argument in `generateMetadata`. This is because we clone the metadata object via `JSON.stringify`/`parse` and then freeze it, to prevent relying on mutating resolved metadata. The replacer/reviver functions we used to clone the metadata didn't properly handle preserving `URL` instances as intended, so they were turned into strings. Because user code already had to handle the case of `metadataBase` potentially being a string at runtime in dev mode, we can just officially reflect that as well in our types, not only for the `ResolvedMetadata` input type, but also for the `Metadata` output type. This also enables `'use cache'` being used in `generateMetadata`, because React currently does not support transporting `URL` instances from one environment to another (e.g. `Server` to `Cache`). Note that all other URL properties in `Metadata` and `ResolvedMetadata` already allowed `string`, so this only affects `metadataBase`. To resolve the ambiguity between dev and prod, we're now always transforming all URL instances to strings, before passing the resolved metadata to `generateMetadata`. This is also reflected in the `ResolvedMetadata` type.
18 lines
391 B
TypeScript
18 lines
391 B
TypeScript
import { Metadata, ResolvingMetadata } from 'next'
|
|
|
|
export default function Page() {
|
|
return null
|
|
}
|
|
|
|
export async function generateMetadata(
|
|
_props,
|
|
parent: ResolvingMetadata
|
|
): Promise<Metadata> {
|
|
const parentMetadata = await parent
|
|
|
|
return {
|
|
metadataBase: parentMetadata.metadataBase?.replace('base', 'case'),
|
|
alternates: { canonical: '/metadata-base/url-string' },
|
|
}
|
|
}
|