Repository: sveltejs/kit (JavaScript)

Issue:
$page.url.hash doesn’t update on moving through browser history
### Describe the bug

I want my app to react on changes in the URL-hash. 
Unfortunately `$page.url.hash` does not update on routing through browser history.


### Reproduction

https://codesandbox.io/p/sandbox/sveltekit-hash-navigation-example-rlxmtv?file=/README.md:3,183

### Logs

_No response_

### System Info

```Shell
System:
    OS: macOS 13.4.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 2.59 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.5.0 - /opt/homebrew/bin/node
    Yarn: 1.22.18 - ~/.yarn/bin/yarn
    npm: 9.8.0 - /opt/homebrew/bin/npm
    pnpm: 7.29.0 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 116.0.5845.96
    Safari: 16.5.2
  npmPackages:
    @sveltejs/adapter-vercel: ^3.0.3 => 3.0.3
    @sveltejs/kit: ^1.23.0 => 1.23.0
    svelte: ^4.2.0 => 4.2.0
    vite: ^4.4.2 => 4.4.9
```


### Severity

serious, but I can work around it

### Additional Information

With the SvelteKit `next`-version it works.


Discussion:
Noticed the same with Edge and Firefox.



Patch:
diff --git a/.changeset/eleven-ads-destroy.md b/.changeset/eleven-ads-destroy.md
new file mode 100644
index 000000000000..3af7595dd6bf
--- /dev/null
+++ b/.changeset/eleven-ads-destroy.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: correctly update `$page.url.hash` when navigating history
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index e9b660f2cd36..174b2413bd12 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1668,10 +1668,12 @@ export function create_client(app, target) {
 					if (event.state[INDEX_KEY] === current_history_index) return;
 
 					const scroll = scroll_positions[event.state[INDEX_KEY]];
+					const url = new URL(location.href);
 
 					// if the only change is the hash, we don't need to do anything...
 					if (current.url.href.split('#')[0] === location.href.split('#')[0]) {
-						// ...except handle scroll
+						// ...except update our internal URL tracking and handle scroll
+						update_url(url);
 						scroll_positions[current_history_index] = scroll_state();
 						current_history_index = event.state[INDEX_KEY];
 						scrollTo(scroll.x, scroll.y);
@@ -1681,7 +1683,7 @@ export function create_client(app, target) {
 					const delta = event.state[INDEX_KEY] - current_history_index;
 
 					await navigate({
-						url: new URL(location.href),
+						url,
 						scroll,
 						keepfocus: false,
 						redirect_chain: [],


Test patch:
diff --git a/packages/kit/test/apps/basics/test/cross-platform/client.test.js b/packages/kit/test/apps/basics/test/cross-platform/client.test.js
index 0e8f32c556fb..598c6e4c356e 100644
--- a/packages/kit/test/apps/basics/test/cross-platform/client.test.js
+++ b/packages/kit/test/apps/basics/test/cross-platform/client.test.js
@@ -641,6 +641,9 @@ test.describe('Routing', () => {
 		await page.locator('[href="/routing/hashes/pagestore"]').click();
 		await expect(page.locator('#window-hash')).toHaveText('#target'); // hashchange doesn't fire for these
 		await expect(page.locator('#page-url-hash')).toHaveText('');
+		await page.goBack();
+		expect(await page.textContent('#window-hash')).toBe('#target');
+		expect(await page.textContent('#page-url-hash')).toBe('#target');
 	});
 
 	test('back button returns to previous route when previous route has been navigated to via hash anchor', async ({