Skip to content

Commit 8d71e2d

Browse files
committed
[breaking] only route pages on the client-side
1 parent 2db01fb commit 8d71e2d

File tree

13 files changed

+29
-40
lines changed

13 files changed

+29
-40
lines changed

.changeset/rotten-gorillas-sort.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+
[breaking] only route pages on the client-side

documentation/docs/07-a-options.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ In certain cases, you may wish to disable this behaviour. Adding a `sveltekit:no
3232

3333
...will prevent scrolling after the link is clicked.
3434

35-
### rel=external
35+
### sveltekit:external
3636

3737
By default, the SvelteKit runtime intercepts clicks on `<a>` elements and bypasses the normal browser navigation for relative (same-origin) URLs that match one of your page routes. We sometimes need to tell SvelteKit that certain links need to be handled by normal browser navigation.
3838

39-
Adding a `rel=external` attribute to a link...
39+
Adding a `sveltekit:external` attribute to a link...
4040

4141
```html
42-
<a rel="external" href="path">Path</a>
42+
<a sveltekit:external href="path">Path</a>
4343
```
4444

45-
...will trigger a browser navigation when the link is clicked.
45+
...will trigger a browser navigation when the link is clicked. `rel=external` and `download` will also trigger this same behavior.

packages/kit/src/core/create_app/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ function generate_client_manifest(manifest_data, base) {
8888
if (params) tuple.push(params);
8989
9090
return `// ${route.a[route.a.length - 1]}\n\t\t[${tuple.join(', ')}]`;
91-
} else {
92-
return `// ${route.file}\n\t\t[${route.pattern}]`;
9391
}
9492
})
9593
.join(',\n\n\t\t')}

packages/kit/src/runtime/app/navigation.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ async function prefetchRoutes_(pathnames) {
4747
? router.routes.filter((route) => pathnames.some((pathname) => route[0].test(pathname)))
4848
: router.routes;
4949

50-
const promises = matching
51-
.filter(/** @returns {r is import('types/internal').CSRPage} */ (r) => r && r.length > 1)
52-
.map((r) => Promise.all(r[1].map((load) => load())));
50+
const promises = matching.map((r) => Promise.all(r[1].map((load) => load())));
5351

5452
await Promise.all(promises);
5553
}

packages/kit/src/runtime/client/renderer.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -369,21 +369,13 @@ export class Renderer {
369369
for (let i = 0; i < info.routes.length; i += 1) {
370370
const route = info.routes[i];
371371

372-
// check if endpoint route
373-
if (route.length === 1) {
374-
return { reload: true, props: {}, state: this.current };
375-
}
376-
377372
// load code for subsequent routes immediately, if they are as
378373
// likely to match the current path/query as the current one
379374
let j = i + 1;
380375
while (j < info.routes.length) {
381376
const next = info.routes[j];
382377
if (next[0].toString() === route[0].toString()) {
383-
// if it's a page route
384-
if (next.length !== 1) {
385-
next[1].forEach((loader) => loader());
386-
}
378+
next[1].forEach((loader) => loader());
387379
j += 1;
388380
} else {
389381
break;

packages/kit/src/runtime/client/router.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ export class Router {
140140
// 2. 'rel' attribute includes external
141141
const rel = (a.getAttribute('rel') || '').split(/\s+/);
142142

143-
if (a.hasAttribute('download') || (rel && rel.includes('external'))) {
143+
if (
144+
a.hasAttribute('sveltekit:external') ||
145+
a.hasAttribute('download') ||
146+
(rel && rel.includes('external'))
147+
) {
144148
return;
145149
}
146150

packages/kit/src/runtime/client/start.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// @ts-expect-error - value will be replaced on build step
1+
// @ts-expect-error - doesn't exist yet. generated by Rollup
22
import Root from 'ROOT';
3-
// @ts-expect-error - value will be replaced on build step
3+
// @ts-expect-error - doesn't exist yet. generated by Rollup
44
import { routes, fallback } from 'MANIFEST';
55
import { Router } from './router.js';
66
import { Renderer } from './renderer.js';

packages/kit/src/runtime/client/types.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CSRComponent, CSRPage, CSRRoute, NormalizedLoadOutput } from 'types/internal';
1+
import { CSRComponent, CSRRoute, NormalizedLoadOutput } from 'types/internal';
22
import { Page } from 'types/page';
33

44
export type NavigationInfo = {
@@ -10,7 +10,7 @@ export type NavigationInfo = {
1010
};
1111

1212
export type NavigationCandidate = {
13-
route: CSRPage;
13+
route: CSRRoute;
1414
info: NavigationInfo;
1515
};
1616

packages/kit/test/apps/basics/src/routes/routing/_tests.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,10 @@ export default function (test, is_dev) {
136136
}
137137
});
138138

139-
test(
140-
'does not attempt client-side navigation to server routes',
141-
'/routing',
142-
async ({ page, clicknav }) => {
143-
await clicknav('[href="/routing/ambiguous/ok.json"]');
144-
assert.equal(await page.textContent('body'), 'ok');
145-
}
146-
);
139+
test('does not attempt client-side navigation to server routes', '/routing', async ({ page }) => {
140+
await page.click('[href="/routing/ambiguous/ok.json"]');
141+
assert.equal(await page.textContent('body'), 'ok');
142+
});
147143

148144
test('allows reserved words as route names', '/routing/const', async ({ page }) => {
149145
assert.equal(await page.textContent('h1'), 'reserved words are okay as routes');
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<h1>Great success!</h1>
22

33
<a href="/routing/a">a</a>
4-
<a href="/routing/ambiguous/ok.json">ok</a>
4+
<a href="/routing/ambiguous/ok.json" sveltekit:external>ok</a>
55
<a href="https://www.google.com">elsewhere</a>
66

7-
<div class='hydrate-test'></div>
7+
<div class="hydrate-test" />

packages/kit/test/apps/basics/src/routes/routing/rest/[...rest]/_tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default function (test) {
2525
assert.equal(await page.textContent('h1'), 'xyz/abc');
2626
assert.equal(await page.textContent('h2'), 'xyz/abc');
2727

28-
await clicknav('[href="/routing/rest/xyz/abc/qwe/deep.json"]');
28+
await page.click('[href="/routing/rest/xyz/abc/qwe/deep.json"]');
2929
assert.equal(await page.textContent('body'), 'xyz/abc/qwe');
3030
});
3131
}

packages/kit/test/apps/basics/src/routes/routing/rest/[...rest]/deep.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
<h1>{$page.params.rest}</h1>
1717
<h2>{rest}</h2>
1818

19-
<a href="/routing/rest/xyz/abc/qwe/deep.json">deep</a>
19+
<a href="/routing/rest/xyz/abc/qwe/deep.json" sveltekit:external>deep</a>
2020
<a href="/routing/rest/xyz/abc">back</a>

packages/kit/types/internal.d.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,7 @@ export interface SSREndpoint {
103103

104104
export type SSRRoute = SSREndpoint | SSRPage;
105105

106-
export type CSRPage = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?];
107-
108-
export type CSREndpoint = [RegExp];
109-
110-
export type CSRRoute = CSREndpoint | CSRPage;
106+
export type CSRRoute = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?];
111107

112108
export interface SSRManifest {
113109
assets: Asset[];

0 commit comments

Comments
 (0)