Skip to content

Commit

Permalink
fix: correctly replace state when using data-sveltekit-replacestate
Browse files Browse the repository at this point in the history
… with a hash link (#9751)

fixes #9546

Checks for the replacestate attribute when clicking on a hash link.
  • Loading branch information
eltigerchino authored Apr 25, 2023
1 parent 1bfcc7a commit d0efa15
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-planes-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: correctly replace state when `data-sveltekit-replacestate` is used with a hash link
7 changes: 5 additions & 2 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,6 @@ export function create_client(app, target) {
if (hash !== undefined && nonhash === location.href.split('#')[0]) {
// set this flag to distinguish between navigations triggered by
// clicking a hash link and those triggered by popstate
// TODO why not update history here directly?
hash_navigating = true;

update_scroll_positions(current_history_index);
Expand All @@ -1541,7 +1540,11 @@ export function create_client(app, target) {
stores.page.set({ ...page, url });
stores.page.notify();

return;
if (!options.replace_state) return;

// hashchange event shouldn't occur if the router is replacing state.
hash_navigating = false;
event.preventDefault();
}

navigate({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<h1 id="hash-target">a</h1>
<a href="#hash-target">hash link</a>
<a href="/routing/hashes/b">b</a>
<a href="#replace-state" data-sveltekit-replacestate>replace state</a>
27 changes: 27 additions & 0 deletions packages/kit/test/apps/basics/test/cross-platform/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,33 @@ test.describe('Routing', () => {
await expect(page.locator('#page-url-hash')).toHaveText('');
});

test('back button returns to previous route when previous route has been navigated to via hash anchor', async ({
page,
clicknav
}) => {
await page.goto('/routing/hashes/a');

await page.locator('[href="#hash-target"]').click();
await clicknav('[href="/routing/hashes/b"]');

await page.goBack();
expect(await page.textContent('h1')).toBe('a');
});

test('replaces state if the data-sveltekit-replacestate router option is specified for the hash link', async ({
page,
clicknav,
baseURL
}) => {
await page.goto('/routing/hashes/a');

await clicknav('[href="#hash-target"]');
await clicknav('[href="#replace-state"]');

await page.goBack();
expect(await page.url()).toBe(`${baseURL}/routing/hashes/a`);
});

test('does not normalize external path', async ({ page, start_server }) => {
const html_ok = '<html><head></head><body>ok</body></html>';
const { port } = await start_server((_req, res) => {
Expand Down
13 changes: 0 additions & 13 deletions packages/kit/test/apps/basics/test/cross-platform/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -743,19 +743,6 @@ test.describe('Routing', () => {
expect(await page.textContent('h1')).toBe('Great success!');
});

test('back button returns to previous route when previous route has been navigated to via hash anchor', async ({
page,
clicknav
}) => {
await page.goto('/routing/hashes/a');

await page.locator('[href="#hash-target"]').click();
await clicknav('[href="/routing/hashes/b"]');

await page.goBack();
expect(await page.textContent('h1')).toBe('a');
});

test('focus works if page load has hash', async ({ page, browserName }) => {
await page.goto('/routing/hashes/target#p2');

Expand Down

0 comments on commit d0efa15

Please sign in to comment.