Deviopath › Next.js

Resolve Metadata Across Layouts

Hard · Metadata

Every layout and page can export metadata. Next.js evaluates them from the root layout down to the page and shallowly merges them: a later segment replaces a whole key (so a page that sets openGraph replaces the parent's openGraph completely, while a page without openGraph inherits it). Write resolveMetadata(layouts, page). This is a simplified model of metadata resolution that covers only a few fields, following the documented rules and the Next.js implementation.

layouts[i] is the metadata of the i-th folder's layout on the way to the page (root first) or null if that folder has no layout; the last entry is the page's own folder. page is the page metadata or null. Fields: title, description, metadataBase (a URL string), openGraph (title, description, images: a string or an array), alternates.canonical.

Title:

- A string title uses the current template: template.replace(/%s/g, title). { default } does the same with default. { absolute } ignores the template. The resolved title also stores the segment's own template (null for a string title).

- The template in effect for a segment is the stored template of the title resolved so far, taken after each segment except the last layout. That is why a layout's template applies to child segments only, never to the page in the same folder, and why a nested layout with a plain string title removes the template for deeper pages.

URLs: openGraph.images and alternates.canonical are resolved when their segment is merged, using that segment's metadataBase if it sets one, otherwise the one merged so far (inputs always provide a base for relative URLs). A value that new URL(value) accepts is already absolute. Otherwise join the base pathname and the value with /, drop empty and . parts, let .. remove the previous part (never above the root) and resolve that path against the base. Images use the full href; for the canonical URL, a pathname of / without query gives just the origin.

Finally, if openGraph exists and has no title (or description), it takes the resolved title (or description). Return { title, description, openGraph, canonical }: title is null when empty, openGraph is { title, description, images } (with null for missing text and [] for no images) or null.

Next: Verify a Signed Webhook