Skip to content

Commit cd72d94

Browse files
authored
fix: prefix route pathname with hash when using resolve with hash routing enabled (#14786)
fixes #14785 This PR changes the client-side resolve implementation to take into account the hash router setting. As a result, it'll add a hash so you get a route such as /base#/my-route which is what you want when hash routing is enabled.
1 parent ab9067b commit cd72d94

File tree

7 files changed

+29
-2
lines changed

7 files changed

+29
-2
lines changed

.changeset/blue-baboons-jam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: include hash when using `resolve` with hash routing enabled

packages/kit/src/exports/vite/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ async function kit({ svelte_config }) {
350350
__SVELTEKIT_PATHS_BASE__: s(kit.paths.base),
351351
__SVELTEKIT_PATHS_RELATIVE__: s(kit.paths.relative),
352352
__SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'),
353+
__SVELTEKIT_HASH_ROUTING__: s(kit.router.type === 'hash'),
353354
__SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server)
354355
};
355356

packages/kit/src/runtime/app/paths/client.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @import { Asset, RouteId, Pathname, ResolvedPathname } from '$app/types' */
22
/** @import { ResolveArgs } from './types.js' */
3-
import { base, assets } from './internal/client.js';
3+
import { base, assets, hash_routing } from './internal/client.js';
44
import { resolve_route } from '../../../utils/routing.js';
55

66
/**
@@ -25,6 +25,8 @@ export function asset(file) {
2525
return (assets || base) + file;
2626
}
2727

28+
const pathname_prefix = hash_routing ? '#' : '';
29+
2830
/**
2931
* Resolve a pathname by prefixing it with the base path, if any, or resolve a route ID by populating dynamic segments with parameters.
3032
*
@@ -51,7 +53,9 @@ export function asset(file) {
5153
export function resolve(...args) {
5254
// The type error is correct here, and if someone doesn't pass params when they should there's a runtime error,
5355
// but we don't want to adjust the internal resolve_route function to accept `undefined`, hence the type cast.
54-
return base + resolve_route(args[0], /** @type {Record<string, string>} */ (args[1]));
56+
return (
57+
base + pathname_prefix + resolve_route(args[0], /** @type {Record<string, string>} */ (args[1]))
58+
);
5559
}
5660

5761
export { base, assets, resolve as resolveRoute };
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export const base = __SVELTEKIT_PAYLOAD__?.base ?? __SVELTEKIT_PATHS_BASE__;
22
export const assets = __SVELTEKIT_PAYLOAD__?.assets ?? base ?? __SVELTEKIT_PATHS_ASSETS__;
33
export const app_dir = __SVELTEKIT_APP_DIR__;
4+
export const hash_routing = __SVELTEKIT_HASH_ROUTING__;

packages/kit/src/types/global-private.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ declare global {
1313
const __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: boolean;
1414
/** True if `config.kit.router.resolution === 'client'` */
1515
const __SVELTEKIT_CLIENT_ROUTING__: boolean;
16+
/** True if `config.kit.router.type === 'hash'` */
17+
const __SVELTEKIT_HASH_ROUTING__: boolean;
1618
/**
1719
* True if any node in the manifest has a server load function.
1820
* Used for treeshaking server load code from client bundles when no server loads exist.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script lang="ts">
2+
import { resolve } from '$app/paths';
3+
</script>
4+
5+
<a href={resolve('/')}>go to home</a>

packages/kit/test/apps/hash-based-routing/test/test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,13 @@ test.describe('hash based navigation', () => {
126126
await expect(page.locator('#button3')).toBeFocused();
127127
await expect(page.locator('button[id="button3"]')).toBeFocused();
128128
});
129+
130+
test('resolve works', async ({ page }) => {
131+
await page.goto('/#/resolve');
132+
await page.locator('a', { hasText: 'go to home' }).click();
133+
await expect(page.locator('p')).toHaveText('home');
134+
const url = new URL(page.url());
135+
expect(url.pathname).toBe('/');
136+
expect(url.hash).toBe('#/');
137+
});
129138
});

0 commit comments

Comments
 (0)