From a8bdcf800b1e96a969ce69547d61b703b0999d87 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 21 Jan 2025 17:29:03 +0800 Subject: [PATCH] fix: correctly handle relative anchors when hash router is enabled (#13356) fixes #13320 This PR enables relative hash links to be used with the hash router so that links such as #example get recognised as a link to the current page. We do this by assuming links that have a hash value starting with #/ links to a route while anything else is probably linking to an element with an id on the current page. --- .changeset/forty-houses-collect.md | 5 +++++ packages/kit/src/runtime/client/utils.js | 6 ++++++ .../hash-based-routing/src/routes/anchor/+page.svelte | 3 +++ packages/kit/test/apps/hash-based-routing/test/test.js | 9 +++++++++ 4 files changed, 23 insertions(+) create mode 100644 .changeset/forty-houses-collect.md create mode 100644 packages/kit/test/apps/hash-based-routing/src/routes/anchor/+page.svelte diff --git a/.changeset/forty-houses-collect.md b/.changeset/forty-houses-collect.md new file mode 100644 index 000000000000..6a48772b3742 --- /dev/null +++ b/.changeset/forty-houses-collect.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: correctly handle relative anchors when using the hash router diff --git a/packages/kit/src/runtime/client/utils.js b/packages/kit/src/runtime/client/utils.js index 28a06d862489..3e121a75e47a 100644 --- a/packages/kit/src/runtime/client/utils.js +++ b/packages/kit/src/runtime/client/utils.js @@ -130,6 +130,12 @@ export function get_link_info(a, base, uses_hash_router) { try { url = new URL(a instanceof SVGAElement ? a.href.baseVal : a.href, document.baseURI); + + // if the hash doesn't start with `#/` then it's probably linking to an id on the current page + if (uses_hash_router && url.hash.match(/^#[^/]/)) { + const route = location.hash.split('#')[1] || '/'; + url.hash = `#${route}${url.hash}`; + } } catch {} const target = a instanceof SVGAElement ? a.target.baseVal : a.target; diff --git a/packages/kit/test/apps/hash-based-routing/src/routes/anchor/+page.svelte b/packages/kit/test/apps/hash-based-routing/src/routes/anchor/+page.svelte new file mode 100644 index 000000000000..3be87857c826 --- /dev/null +++ b/packages/kit/test/apps/hash-based-routing/src/routes/anchor/+page.svelte @@ -0,0 +1,3 @@ +go to #test + +

#test

diff --git a/packages/kit/test/apps/hash-based-routing/test/test.js b/packages/kit/test/apps/hash-based-routing/test/test.js index 23666ed5e562..d7962d380ea4 100644 --- a/packages/kit/test/apps/hash-based-routing/test/test.js +++ b/packages/kit/test/apps/hash-based-routing/test/test.js @@ -89,4 +89,13 @@ test.describe('hash based navigation', () => { url = new URL(page.url()); expect(url.hash).toBe('#/reroute-b'); }); + + test('relative anchor works', async ({ page }) => { + await page.goto('/#/anchor'); + + await page.locator('a[href="#test"]').click(); + await expect(page.locator('#test')).toHaveText('#test'); + const url = new URL(page.url()); + expect(url.hash).toBe('#/anchor#test'); + }); });