mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #249] [MERGED] fix: wire up RouterContext.Provider in Pages Router #417
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#417
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/249
Author: @yunus25jmi1
Created: 3/4/2026
Status: ✅ Merged
Merged: 3/4/2026
Merged by: @southpolesteve
Base:
main← Head:fix/issue-239-pages-router-context-provider📝 Commits (1)
ed13636fix: wire up RouterContext.Provider in Pages Router (#239)📊 Changes
4 files changed (+204 additions, -37 deletions)
View changed files
📝
packages/vinext/src/index.ts(+7 -1)📝
packages/vinext/src/server/dev-server.ts(+34 -4)📝
packages/vinext/src/shims/router.ts(+82 -32)📝
tests/shims.test.ts(+81 -0)📄 Description
Fixes #239
Problem
next/compat/router'suseRouter()always returnsnullin Pages Router because no<RouterContext.Provider>wraps the page tree. In Next.js, the framework renders aRouterContext.Providerat the top level so bothnext/routerandnext/compat/routerread from the same context.Root-Cause Fix
Added
wrapWithRouterContext(element)to thenext/routershim — a plain function (not a React component) that:window.location+Routersingleton (client)<RouterContext.Provider value={routerValue}>This avoids the duplicate-state problem that a hook-based component would create. There's a single source of truth for the router context value, matching Next.js's architecture.
Why not a React component with hooks?
A
PagesRouterProvidercomponent callinguseRouter()would create its ownuseState/useEffect/useMemoinstance — a second, independent router state alongside every other component that also callsuseRouter(). The plain-function approach builds the value once per render pass with zero hook overhead.Changes
shims/router.tswrapWithRouterContext()export + wrap innavigateClient()server/dev-server.tsindex.tsrenderPage()+ ISR re-rendertests/shims.test.tsTests
useRouterreturnsnullwithout provider (App Router behavior)useRouterreturns full router whenwrapWithRouterContextwraps treeuseRouterreflects SSR context (pathname,query,asPath)wrapWithRouterContextis exported fromnext/routerAll 535 shims tests pass.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.