Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Next.js: basePath is concatenated onto absolute router.push hrefs, corrupting navigation transaction names

Aperta Adatta ai principianti
#24,672 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
75/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
javascript, next.js, typescript

Direzione di ricerca

Il problema si trova nei file di strumentazione del routing client di Next.js: build/cjs/client/routing/appRouterRoutingInstrumentation.js e probabilmente un file simile per il percorso della patch del router. Cerca l'assegnazione di normalizedHref. La correzione consiste nel proteggere la concatenazione in modo che si applichi solo ai percorsi relativi alla radice (quelli che iniziano con '/'), rispecchiando la logica di addPathPrefix di Next.js. Testa configurando un'app Next.js App Router con un basePath, utilizzando Sentry e verificando i nomi delle transazioni di navigazione dopo un router.push con un URL assoluto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Browser Bug Next.js Traces Waiting for: Product Owner

Summary

@sentry/nextjs prepends basePath to the router.push / router.replace argument with an unguarded string concatenation. When the argument is an absolute URL, the two are glued together and the navigation span is named something like:

/hhttps://example.com/login

instead of /login. The navigation itself works correctly — only the span name is corrupted — so this shows up as junk entries in the transaction list and in dashboards, not as a user-facing failure.

Versions

  • @sentry/nextjs 10.22.0; also present in 11.0.0 (latest at time of writing)
  • next 15.5.18, App Router, basePath: '/h'
  • Affects both navigation instrumentation modes (see below)

Root cause

build/cjs/client/routing/appRouterRoutingInstrumentation.js, in the transition-start-hook path:

const basePath = process.env._sentryBasePath ?? globalWithInjectedBasePath._sentryBasePath;
const normalizedHref = basePath && !href.startsWith(basePath) ? `${basePath}${href}` : href;
const unparameterizedPathname = new URL(normalizedHref, WINDOW.location.href).pathname;

With basePath = '/h' and href = 'https://example.com/login', href.startsWith('/h') is false, so the result is '/h' + 'https://example.com/login', and new URL(...).pathname faithfully returns /hhttps://example.com/login.

The same expression appears in the router-patch path, so both modes are affected.

Note the second-order effect: an href that already carries the base path — https://example.com/h/payments — is still concatenated, because as a string it starts with https, not /h.

Why Next.js itself is unaffected

Next's own addPathPrefix guards on the leading slash:

function addPathPrefix(path, prefix) {
  if (!path.startsWith('/') || !prefix) {
    return path;
  }
  ...
}

So Next leaves absolute URLs alone, treats a same-origin absolute URL as an internal navigation, and routes correctly. Only the Sentry span name diverges from reality.

Reproduction

  1. Next.js App Router app with basePath: '/h' and @sentry/nextjs client instrumentation.
  2. Call router.push('https://<same-origin>/login') — or, more realistically, have a server component throw redirect('https://<same-origin>/login'). Next's RedirectBoundary catches it and calls router.push(url) internally, so this needs no unusual application code.
  3. Observe the resulting navigation transaction name.

Expected: /login
Actual: /hhttps://<same-origin>/login

Absolute redirect targets are not exotic in a basePath app: Next's server redirect() runs the location through addPathPrefix, so an absolute URL is the documented way to send a user to a path outside the base path. Those same absolute URLs then reach the client router whenever the redirect is hit during a soft navigation.

We see seven distinct corrupted names in production across two apps over 90 days.

Suggested fix

Mirror Next's guard — only prefix root-relative paths:

-const normalizedHref = basePath && !href.startsWith(basePath) ? `${basePath}${href}` : href;
+const normalizedHref =
+  basePath && href.startsWith('/') && !href.startsWith(basePath) ? `${basePath}${href}` : href;

Both occurrences need it. The router-patch branch additionally guards typeof href === 'string' already, which the hook branch does not.


Investigated and written with Claude Code.

Lingua principale
TypeScript
Stelle
8.7k
Fork
1.9k
Merge medio
1g 16h
PR unite (30g)
576

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di getsentry/sentry-javascript

Tutte le issue di getsentry/sentry-javascript

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.