You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Next.js app router: router.back()/router.forward() navigations are tagged browser.popstate under span streaming #23909
With span streaming enabled, a router.back() or router.forward() navigation in the Next.js app router produces a navigation span with navigation.type: 'browser.popstate' instead of router.back / router.forward.
Under traceLifecycle: 'static' the same navigations are tagged router.back / router.forward.
Evidence
Observed in the nextjs-app-dir E2E app (Next 14.2.35, production build) while porting it to span streaming in #23905. The streamed event dump for a full run contains no router.back, router.forward or router.traverse value at all — only browser.popstate (6), router.push (7) and router.replace (2). The corresponding navigation spans:
The transaction-based versions of these two tests pass on develop today, so this is specific to streaming.
Likely mechanism
In packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts, router-patch mode (which is what Next 14 uses, since it has no onRouterTransitionStart hook) starts a navigation span tagged router.back/router.forward with the placeholder name INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME, because back()/forward() carry no href.
The popstate listener is then supposed to rename that same span:
if(currentRouterPatchingNavigationSpanRef.current?.isRecording()){currentRouterPatchingNavigationSpanRef.current.updateName(spanName);// ... does not touch navigation.type}else{// creates a NEW span tagged 'browser.popstate'}
Under streaming the ref appears to no longer be recording when popstate fires, so the else branch creates a second span tagged browser.popstate, and the original placeholder-named span is filtered out by the ignoreSpans entry that matches the placeholder name. The net effect is that the back/forward distinction is lost.
Impact
navigation.type no longer distinguishes back/forward from a plain popstate under streaming, for app router apps in router-patch mode.
Status
The two affected E2E tests (Creates a navigation span for \router.back()`and... `router.forward()``) are skipped in #23905 with a pointer to this issue, rather than having their expectations relaxed.
Activity
linear-code commentedon Sep 2, 2026
JS-3527
test(e2e): Port nextjs-app-dir to span streaming
test(e2e): Port nextjs-app-dir to span streaming
test(e2e): Port nextjs-app-dir to span streaming (#23905)
fix(nextjs): Keep router.back/forward navigation type under span stre…
github-actions commentedon Sep 23, 2026
A PR closing this issue has just been released 🚀
This issue was referenced by PR #24074, which was included in the 11.0.0 release.