Skip to content
5 changes: 5 additions & 0 deletions .changeset/great-kangaroos-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: update `$page.url` when URL hash is directly altered in address bar
17 changes: 14 additions & 3 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,10 @@ export function create_client(app, target) {
callbacks.before_navigate.forEach((fn) => fn(navigation));
}

const url = new URL(location.href, document.baseURI);
update_url_and_page_store_notifying_with_url(url);


if (should_block) {
e.preventDefault();
e.returnValue = '';
Expand Down Expand Up @@ -1570,9 +1574,7 @@ export function create_client(app, target) {

update_scroll_positions(current_history_index);

current.url = url;
stores.page.set({ ...page, url });
stores.page.notify();
update_url_and_page_store_notifying_with_url(url);

return;
}
Expand Down Expand Up @@ -1719,6 +1721,15 @@ export function create_client(app, target) {
stores.navigating.set(null);
}
});

/**
* @param {URL} url
*/
function update_url_and_page_store_notifying_with_url(url) {
current.url = url;
stores.page.set({ ...page, url });
stores.page.notify();
}
},

_hydrate: async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<div id="store-data">{JSON.stringify($page.data)}</div>
<div id="store-error">{$page.error?.message}</div>
<div id="page-url">{$page.url}</div>

<nav>
<a href="/store/data/xxx">xxx</a> <a href="/store/data/yyy">yyy</a>
Expand Down
20 changes: 20 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,26 @@ test.describe('$app/stores', () => {
expect(await page.textContent('#nav-status')).toBe('not currently navigating');
}
});

test("url's hash is updated when it is modified in the address bar", async ({
page,
javaScriptEnabled
}) => {
if (javaScriptEnabled) {
const baseUrl = '/store/data/www';
// Go to page where store data, as well as URL, are displayed
await page.goto(baseUrl);

// Change hash to #2 in address bar
await page.evaluate(() => {
history.pushState({}, '', '#2');
});

expect(await page.locator('#page-url').textContent({ timeout: 5000 })).toMatch(/#2$/, {
timeout: 5000
});
}
});
});

test.describe('searchParams', () => {
Expand Down