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); });