cloudflare / cloudflare/vinext

Pages Router: `window.next.router` global not exposed during hydration

Open
#1,329 4 comments 0 reactions 0 assignees View on GitHub
adapter-api-e2e help wanted
Dominant language
TypeScript
Stars
8.8k
Forks
406
Avg merge
2d 6h
Merged PRs (30d)
120

Description

> *This issue was created by an agent analysing CI failures from the [Next.js Deploy Suite](https://github.com/cloudflare/vinext/actions/runs/26163751905) (vinext `main` vs Next.js `v16.2.6`, 2026-05-20).*

## Problem

vinext does not expose `window.next = { router }` during Pages Router client-side hydration. In Next.js, `packages/next/src/client/index.tsx` sets this global during hydration, and it is the only programmatic way to trigger imperative client-side navigation outside React components.

Every test that calls `browser.eval('next.router.push(...)')` or reads `browser.eval('next.router.pathname')` fails immediately with:

```
TypeError: Cannot read properties of undefined (reading 'router')
```

or:

```
ReferenceError: next is not defined
```

Because the navigation never fires, downstream assertions (waiting for page content, checking URLs, verifying router events, checking `window.__SAME_PAGE`) all time out.

## Estimated Impact

~80 test failures across the deploy suite.

## Affected Test Suites

- `test/e2e/middleware-general/test/node-runtime.test.ts` (34 failures)
- `test/e2e/middleware-general/test/index.test.ts` (32 failures)
- `test/e2e/middleware-rewrites/test/index.test.ts` (21 failures)
- `test/e2e/trailing-slashes/with-trailing-slash.test.ts` (20 failures)
- `test/e2e/trailing-slashes/without-trailing-slash.test.ts` (20 failures)
- `test/e2e/basepath/query-hash.test.ts` (10 failures)
- `test/e2e/basepath/router-events.test.ts` (4 failures)
- `test/e2e/use-router-with-rewrites/use-router-with-rewrites.test.ts` (7 failures)
- `test/e2e/with-router/index.test.ts` (3 failures)
- `test/e2e/ignore-invalid-popstateevent/*.test.ts` (5 failures)

## Recommendation

1. **Reproduce first in vinext's own test suite.** Before submitting a PR, add a test case in the relevant `tests/*.test.ts` file that verifies `window.next.router` is exposed on Pages Router pages after hydration. Confirm it fails, then implement the fix.

2. **Study the Next.js implementation.** Look at `packages/next/src/client/index.tsx` in the Next.js source to understand what properties are set on `window.next` and when. At minimum, `window.next.router` must expose `.pathname`, `.query`, `.push()`, `.replace()`, `.events`, and other standard router properties.

3. **Wire up the global in the Pages Router client entry.** The vinext Pages Router client entry (or hydration code) needs to set `window.next = { version, router }` after the router is initialized, mirroring what Next.js does.

4. **Verify dev/prod parity.** Ensure the global is available in both development and production builds.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the failure in a relevant tests/*.test.ts file, such as test/e2e/with-router/index.test.ts, and add a hydration check for window.next.router. Read packages/next/src/client/index.tsx to compare the expected global and inspect the vinext Pages Router client entry. Done means the router properties and navigation methods are available after hydration in both development and production builds.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.