Skip to content

fix(next/routing): keep the hash out of the pathname and query of a destination - #97004

Draft
yogesh968 wants to merge 2 commits into
vercel:canaryfrom
yogesh968:fix/routing-destination-hash
Draft

fix(next/routing): keep the hash out of the pathname and query of a destination#97004
yogesh968 wants to merge 2 commits into
vercel:canaryfrom
yogesh968:fix/routing-destination-hash

Conversation

@yogesh968

Copy link
Copy Markdown

What?

applyDestination in packages/next-routing/src/destination.ts mishandled a # in a routing destination. The fragment ended up inside the pathname, or inside a query value:

  • /new#section → pathname /new%23section
  • /new?ref=email#section → query value ref=email#section

Why?

The destination was split manually on ?, and everything before the first ? was assigned straight to newUrl.pathname. Nothing ever looked for #, so:

  • with no query string, the whole path#hash string became the pathname, and the URL setter percent-encoded the # into %23
  • with a query string, the hash stayed glued to the last query value

How?

Parse the destination with the URL constructor (relative to the current URL) instead of splitting on ?. The parser splits pathname, query and hash the way a browser does, so the hash lands on newUrl.hash and query values stay clean. Query merging is unchanged — the parsed searchParams are still copied onto the existing URL, overwriting on key collision.

Tests added in packages/next-routing/src/__tests__/redirects.test.ts covering a hash-only destination, hash + query, multiple ?, and a destination with no hash (regression guard).

webdev1-hub and others added 2 commits August 7, 2026 15:54
…estination

The destination was split on `?` and everything before it became the pathname,
so a `#` was never recognised:

- /new#section produced the pathname /new%23section
- /new?ref=email#section produced the query value "email#section"

Parse the destination with the URL constructor instead, which splits pathname,
query and hash the way a browser does.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants