diff --git a/.changeset/few-heads-dress.md b/.changeset/few-heads-dress.md new file mode 100644 index 00000000..747bb4b2 --- /dev/null +++ b/.changeset/few-heads-dress.md @@ -0,0 +1,5 @@ +--- +'sv-router': patch +--- + +Add basename in anchors href diff --git a/src/create-router.svelte.js b/src/create-router.svelte.js index 42887d13..64c0e92d 100644 --- a/src/create-router.svelte.js +++ b/src/create-router.svelte.js @@ -134,7 +134,7 @@ function navigate(path, options = {}) { path = constructPath(path, options.params); if (base.name === '#') { - path = new URL(path).hash; + path = new URL(path.replace('/#', '')).hash; } else if (options.hash && !options.hash.startsWith('#')) { options.hash = '#' + options.hash; } @@ -200,8 +200,10 @@ export async function onNavigate(path, options = {}) { url.hash = options.hash || ''; if (base.name === '#') { url.hash = path; + } else if (base.name && !path.startsWith(base.name)) { + url.pathname = join(base.name, path); } else { - url.pathname = base.name ? join(base.name, path) : path; + url.pathname = path; } const historyMethod = options.replace ? 'replaceState' : 'pushState'; globalThis.history[historyMethod](options.state || {}, '', url.toString()); diff --git a/src/helpers/is-active.js b/src/helpers/is-active.js index b4467511..239f6d86 100644 --- a/src/helpers/is-active.js +++ b/src/helpers/is-active.js @@ -34,7 +34,7 @@ function compare(compareFn, pathname, params) { if (params) { if (base.name === '#') { - return compareFn(location.pathname, new URL(constructPath(pathname, params)).hash.slice(1)); + return compareFn(location.pathname, constructPath(pathname, params).replace('/#', '')); } else { return compareFn(location.pathname, constructPath(pathname, params)); } diff --git a/src/helpers/utils.js b/src/helpers/utils.js index 53776f89..eff0e462 100644 --- a/src/helpers/utils.js +++ b/src/helpers/utils.js @@ -13,11 +13,10 @@ export function constructPath(path, params) { } if (base.name === '#') { - const url = new URL(globalThis.location.toString()); - url.hash = path; - url.search = ''; - - return url.toString(); + if (path === '/') { + return '/#/'; + } + return join('#', path); } return path; diff --git a/tests/utils.test.js b/tests/utils.test.js index 8a2415ff..2b59ba89 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -31,27 +31,37 @@ describe('constructPath (hash-based)', () => { it('should return the original path when no params are provided', () => { const result = constructPath('/posts'); - expect(result).toBe('http://localhost:3000/#/posts'); + expect(result).toBe('/#/posts'); }); it('should replace a single param in the path', () => { const result = constructPath('/posts/:id', { id: '123' }); - expect(result).toBe('http://localhost:3000/#/posts/123'); + expect(result).toBe('/#/posts/123'); }); it('should replace multiple params in the path', () => { const result = constructPath('/posts/:id/comments/:commentId', { id: '123', commentId: '456' }); - expect(result).toBe('http://localhost:3000/#/posts/123/comments/456'); + expect(result).toBe('/#/posts/123/comments/456'); }); }); describe('constructUrl', () => { it('should create a path with search and hash', () => { + base.name = undefined; const result = constructUrl('/posts', { search: { q: 'test' }, hash: 'hash', }); - expect(result).toBe('http://localhost:3000/#/posts?q=test#hash'); + expect(result).toBe('/posts?q=test#hash'); + }); + + it('should create a path with search and hash (hash-based)', () => { + base.name = '#'; + const result = constructUrl('/posts', { + search: { q: 'test' }, + hash: 'hash', + }); + expect(result).toBe('/#/posts?q=test#hash'); }); });