mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #996] [MERGED] refactor(metadata): share route pattern helpers #1009
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#1009
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/996
Author: @NathanDrake2406
Created: 5/1/2026
Status: ✅ Merged
Merged: 5/1/2026
Merged by: @james-elicx
Base:
main← Head:nathan/metadata-helper-dedupe📝 Commits (3)
f4160f7refactor(metadata): share route pattern helpers1899e97fix(routing): preserve prototype-named route paramsdeea845fix(routing): preserve literal intercept target segments📊 Changes
8 files changed (+281 additions, -226 deletions)
View changed files
➕
packages/vinext/src/routing/route-pattern.ts(+139 -0)📝
packages/vinext/src/server/app-rsc-route-matching.ts(+3 -30)📝
packages/vinext/src/server/file-based-metadata.ts(+20 -107)📝
packages/vinext/src/server/metadata-route-build-data.ts(+2 -14)📝
packages/vinext/src/server/metadata-routes.ts(+2 -41)📝
packages/vinext/src/shims/metadata.tsx(+22 -34)📝
tests/app-rsc-route-matching.test.ts(+24 -0)➕
tests/route-pattern.test.ts(+69 -0)📄 Description
What this changes
This is a follow-up to James's review comments on #891 about duplicated metadata helper logic:
The PR adds a normal routing module,
packages/vinext/src/routing/route-pattern.ts, that owns app-route segment pattern conversion, dynamic segment filling, and pattern matching. Metadata route build data, metadata route runtime matching, file-based metadata head injection, and App RSC intercept matching now consume that shared behavior instead of keeping local copies.It also consolidates the duplicated icon descriptor normalization in both
file-based-metadata.tsandmetadata.tsxwithout changing observable metadata output.Why
The codegen boundary should describe the app shape, while normal modules implement behavior. The previous #891 implementation already moved most runtime metadata work out of generated entries, but some generic route behavior still lived inside metadata-specific modules. That made the code harder to audit and made future routing parity fixes more likely to fork across metadata, App RSC, and shim paths.
Approach
routing/route-pattern.ts.Next.js references
The shared helper is intentionally aligned with the same observable contracts Next uses in separate places:
packages/next/src/lib/metadata/get-metadata-route.tspackages/next/src/server/server-utils.tspackages/next/src/shared/lib/router/utils/route-matcher.tsValidation
vp test run tests/route-pattern.test.ts tests/metadata-route-build-data.test.ts tests/metadata-routes.test.ts tests/file-based-metadata.test.ts tests/app-rsc-route-matching.test.ts tests/shims.test.tspassed: 952 tests.vp checkpassed: 1071 files formatted, 457 files checked with no warnings, lint errors, or type errors.vp run vinext#buildpassed. The existing virtual-module unresolved import warnings are preserved build behavior.Risks / follow-ups
The new matcher accepts catch-all pattern parts before a suffix, which metadata image routes need for
generateImageMetadata()ID suffixes. App RSC intercept matching now uses the same matcher, but normal App route matching still goes through the route trie.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.