Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

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

Geschlossen Anfängerfreundlich
#24,672 2 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@Lms24 arbeitet bereits daran.

Seit 24.9.2026.

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
75/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv

Rechercherichtung

Das Problem liegt in den Next.js-Client-Routing-Instrumentierungsdateien: build/cjs/client/routing/appRouterRoutingInstrumentation.js und wahrscheinlich einer ähnlichen Datei für den Router-Patch-Pfad. Suchen Sie nach der Zuweisung von normalizedHref. Die Lösung besteht darin, die Verkettung so abzusichern, dass sie nur auf root-relative Pfade (solche, die mit '/' beginnen) angewendet wird, analog zur Logik von Next.js addPathPrefix. Testen Sie, indem Sie eine Next.js-App-Router-App mit einem basePath einrichten, Sentry verwenden und die Navigations-Transaktionsnamen nach einem router.push mit einer absoluten URL überprüfen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Browser Bug Next.js Traces

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.

Vorherrschende Sprache
TypeScript
Sterne
8.7k
Forks
1.9k
Ø Merge
1 T. 17 Std.
Gemergte PRs (30 T.)
523

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus getsentry/sentry-javascript

Alle Issues in getsentry/sentry-javascript

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.