From 361b32c7cdb5257f3b4db2ef0997cdbce78ccbab Mon Sep 17 00:00:00 2001 From: Mathias Picker <48158184+MathiasWP@users.noreply.github.com> Date: Fri, 27 Feb 2026 21:41:56 +0100 Subject: [PATCH] fix: SvelteURL search setter uses unnormalized value (#17828) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - The `SvelteURL` `search` setter stored the raw input `value` instead of `super.search`, unlike every other setter in the class - This caused `url.search` to return incorrect values when the URL API normalizes the input (e.g. adding the `?` prefix, or stripping a lone `?`) - For example: `url.search = 'foo=bar'` would return `'foo=bar'` instead of `'?foo=bar'` ## Test plan - [x] Added `url.search normalizes value` test covering: - Setting search without `?` prefix - Setting search with `?` prefix (existing behavior) - Setting search to lone `?` (normalized to `""`) - [x] All existing reactivity tests pass (46/46) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 --- .../fix-svelte-url-search-normalization.md | 5 ++++ packages/svelte/src/reactivity/url.js | 2 +- packages/svelte/src/reactivity/url.test.ts | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-svelte-url-search-normalization.md diff --git a/.changeset/fix-svelte-url-search-normalization.md b/.changeset/fix-svelte-url-search-normalization.md new file mode 100644 index 0000000000..013acfd551 --- /dev/null +++ b/.changeset/fix-svelte-url-search-normalization.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: SvelteURL `search` setter now returns the normalized value, matching native URL behavior diff --git a/packages/svelte/src/reactivity/url.js b/packages/svelte/src/reactivity/url.js index dfede23f6e..549a20baa7 100644 --- a/packages/svelte/src/reactivity/url.js +++ b/packages/svelte/src/reactivity/url.js @@ -171,7 +171,7 @@ export class SvelteURL extends URL { set search(value) { super.search = value; - set(this.#search, value); + set(this.#search, super.search); this.#searchParams[REPLACE](super.searchParams); } diff --git a/packages/svelte/src/reactivity/url.test.ts b/packages/svelte/src/reactivity/url.test.ts index 46430a90a8..a76efeb2b2 100644 --- a/packages/svelte/src/reactivity/url.test.ts +++ b/packages/svelte/src/reactivity/url.test.ts @@ -115,6 +115,35 @@ test('url.searchParams', () => { cleanup(); }); +test('url.search normalizes value', () => { + const url = new SvelteURL('https://svelte.dev'); + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + log.push(url.search); + }); + }); + + flushSync(() => { + // setting without ? prefix — URL normalizes to "?foo=bar" + url.search = 'foo=bar'; + }); + + flushSync(() => { + url.search = '?baz=qux'; + }); + + flushSync(() => { + // lone "?" is normalized to "" + url.search = '?'; + }); + + assert.deepEqual(log, ['', '?foo=bar', '?baz=qux', '']); + + cleanup(); +}); + test('SvelteURL instanceof URL', () => { assert.ok(new SvelteURL('https://svelte.dev') instanceof URL); });