mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #891] [MERGED] feat(app-router): feed file metadata routes into head output #923
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#923
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/891
Author: @NathanDrake2406
Created: 4/25/2026
Status: ✅ Merged
Merged: 4/30/2026
Merged by: @james-elicx
Base:
main← Head:nathanfix-static-metadata-parity📝 Commits (1)
d9d8d77feat(app-router): feed file metadata routes into head output📊 Changes
55 files changed (+5277 additions, -949 deletions)
View changed files
📝
knip.ts(+2 -0)📝
package.json(+0 -1)📝
packages/vinext/package.json(+1 -0)📝
packages/vinext/src/entries/app-rsc-entry.ts(+41 -97)📝
packages/vinext/src/entries/app-rsc-manifest.ts(+4 -55)📝
packages/vinext/src/server/app-browser-entry.ts(+35 -1)📝
packages/vinext/src/server/app-page-boundary-render.ts(+76 -6)📝
packages/vinext/src/server/app-page-cache.ts(+21 -0)📝
packages/vinext/src/server/app-page-head.ts(+334 -67)📝
packages/vinext/src/server/app-prerender-endpoints.ts(+23 -5)➕
packages/vinext/src/server/app-prerender-static-params.ts(+21 -0)➕
packages/vinext/src/server/file-based-metadata.ts(+842 -0)➕
packages/vinext/src/server/metadata-route-build-data.ts(+264 -0)➕
packages/vinext/src/server/metadata-route-response.ts(+374 -0)📝
packages/vinext/src/server/metadata-routes.ts(+210 -32)📝
packages/vinext/src/shims/cache.ts(+1 -1)📝
packages/vinext/src/shims/metadata.tsx(+162 -45)➕
packages/vinext/src/shims/thenable-params.ts(+41 -0)📝
pnpm-lock.yaml(+3 -3)📝
tests/__snapshots__/entry-templates.test.ts.snap(+202 -577)...and 35 more files
📄 Description
What this changes
Fixes #884 by folding App Router file-convention metadata into rendered head output and by serving the corresponding static and dynamic metadata assets with the route metadata needed by the head renderer.
This covers static icon/apple/Open Graph/Twitter/manifest files, static social image
.alt.txtfiles, content-hashed injected URLs, image dimensions and content types, placeholder URLs for static metadata under dynamic segments, numbered dynamic image route variants such asopengraph-image2.tsx, andgenerateImageMetadata()id routes.Follow-up review fixes in this branch also keep metadata route generation thin, add path-specific read failures for scanned static metadata, preserve URL-valued metadata without deep cloning, scope layout metadata params to the layout segment, include active and intercepted parallel route metadata in head resolution, preserve static
manifest.jsonURLs, avoid parsing image dimensions for non-image metadata files, aligngenerateSitemaps()id handling with Next, and seed root params around prerendergenerateStaticParams().Why
vinext could serve metadata files as routes, but those files were not consistently reflected in
metadata.icons,metadata.openGraph.images,metadata.twitter.images, ormetadata.manifestbeforeMetadataHeadrendered. That meant browsers and crawlers could miss file-convention metadata even when the asset URL itself existed.The failure mode was also too quiet for static metadata files: if a scanned file could not be read, bad state could travel into missing hashes or empty metadata responses. Static file read failures now fail during entry generation with the specific file path.
Approach
URLvalues such asmetadataBasesurvive file metadata applicationopengraph-image.alt.txtandtwitter-image.alt.txtcontent in rendered OG/Twitter image alt metadatamanifest.jsonURLs and serve static manifests withapplication/manifest+jsongenerateImageMetadata()id routes and validate generated ids before calling the selected image handlergenerateSitemaps()ids, matching NextNon-goals
metadataBaseorbasePathparity beyond the file-based metadata paths touched heregenerateImageMetadata()is not usedValidation
vp checkvp test run tests/app-page-head.test.ts tests/file-based-metadata.test.ts tests/metadata-routes.test.ts tests/metadata-route-response.test.ts tests/entry-templates.test.ts tests/app-page-boundary-render.test.tsvp test run tests/app-router.test.ts tests/metadata-route-response.test.tsNext.js sources referenced
packages/next/src/lib/metadata/resolve-metadata.tspackages/next/src/build/webpack/loaders/next-metadata-image-loader.tspackages/next/src/build/webpack/loaders/next-metadata-route-loader.tspackages/next/src/lib/metadata/get-metadata-route.tspackages/next/src/lib/metadata/is-metadata-route.tstest/e2e/app-dir/metadata/metadata.test.tstest/e2e/app-dir/metadata-dynamic-routes/index.test.tstest/e2e/app-dir/metadata-static-file/🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.