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
fix: encode path params per RFC 3986 path-segment rules in href/generatePath
Follow-up to #15277, which fixed `href()` to URL-encode param values to
match `generatePath()`. Both now encode with `encodeURIComponent`, which
implements *query-string* escaping — a stricter rule than URL paths
require. This over-escapes characters that RFC 3986 explicitly allows
literally in a path segment:
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
`$ & + , ; = : @` only act as delimiters in a query string; in a path
segment they carry no special meaning, and browsers keep them literal in
`location.pathname`. Encoding them needlessly rewrites URLs:
href("/releases/:v", { v: "1.0.0+1" })
// before: /releases/1.0.0%2B1
// after: /releases/1.0.0+1
which breaks apps that compare generated URLs against
`window.location.pathname` (the browser reports the literal `+`), churns
canonical/shareable URLs, and makes `href()` output disagree with what
users see in the address bar.
Changes:
- Add an internal `encodePathParam()` that escapes structural/unsafe
characters (`/ ? # %`, whitespace, non-ASCII) exactly as before, but
restores the RFC 3986 pchar set that `encodeURIComponent` over-escapes
- Use it for named params in `generatePath()` and for named params and
splat segments in `href()`
- Document path-segment vs query-string encoding semantics (with the RFC
reference) in the `href()` and `generatePath()` JSDoc
- Update and extend unit tests; add a change file
Behavior is unchanged for every character outside `$ & + , ; = : @`, and
`generatePath()`'s splat values remain un-encoded, as before.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Encode path params in `href`/`generatePath` per RFC 3986 path-segment rules instead of `encodeURIComponent`
2
+
3
+
- Characters that are valid literally in a path segment (`$ & + , ; = : @` — RFC 3986 `pchar`) are no longer percent-encoded, so values like a semver build `1.0.0+1` interpolate unchanged instead of becoming `1.0.0%2B1`
4
+
- Structural/unsafe characters (`/ ? # %`, whitespace, non-ASCII) are still escaped exactly as before
0 commit comments