Skip to content

Commit

Permalink
[breaking] only route pages on the client-side
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Oct 21, 2021
1 parent 2db01fb commit 91476ca
Show file tree
Hide file tree
Showing 13 changed files with 27 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-gorillas-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

[breaking] only route pages on the client-side
8 changes: 4 additions & 4 deletions documentation/docs/07-a-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ In certain cases, you may wish to disable this behaviour. Adding a `sveltekit:no

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

### rel=external
### sveltekit:external

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.

Adding a `rel=external` attribute to a link...
Adding a `sveltekit:external` attribute to a link...

```html
<a rel="external" href="path">Path</a>
<a sveltekit:external href="path">Path</a>
```

...will trigger a browser navigation when the link is clicked.
...will trigger a browser navigation when the link is clicked. `rel=external` and `download` will also trigger this same behavior.
2 changes: 0 additions & 2 deletions packages/kit/src/core/create_app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ function generate_client_manifest(manifest_data, base) {
if (params) tuple.push(params);
return `// ${route.a[route.a.length - 1]}\n\t\t[${tuple.join(', ')}]`;
} else {
return `// ${route.file}\n\t\t[${route.pattern}]`;
}
})
.join(',\n\n\t\t')}
Expand Down
4 changes: 1 addition & 3 deletions packages/kit/src/runtime/app/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ async function prefetchRoutes_(pathnames) {
? router.routes.filter((route) => pathnames.some((pathname) => route[0].test(pathname)))
: router.routes;

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

await Promise.all(promises);
}
10 changes: 1 addition & 9 deletions packages/kit/src/runtime/client/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,21 +369,13 @@ export class Renderer {
for (let i = 0; i < info.routes.length; i += 1) {
const route = info.routes[i];

// check if endpoint route
if (route.length === 1) {
return { reload: true, props: {}, state: this.current };
}

// load code for subsequent routes immediately, if they are as
// likely to match the current path/query as the current one
let j = i + 1;
while (j < info.routes.length) {
const next = info.routes[j];
if (next[0].toString() === route[0].toString()) {
// if it's a page route
if (next.length !== 1) {
next[1].forEach((loader) => loader());
}
next[1].forEach((loader) => loader());
j += 1;
} else {
break;
Expand Down
6 changes: 5 additions & 1 deletion packages/kit/src/runtime/client/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,11 @@ export class Router {
// 2. 'rel' attribute includes external
const rel = (a.getAttribute('rel') || '').split(/\s+/);

if (a.hasAttribute('download') || (rel && rel.includes('external'))) {
if (
a.hasAttribute('sveltekit:external') ||
a.hasAttribute('download') ||
(rel && rel.includes('external'))
) {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/client/start.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-expect-error - value will be replaced on build step
// @ts-expect-error - doesn't exist yet. generated by Rollup
import Root from 'ROOT';
// @ts-expect-error - value will be replaced on build step
// @ts-expect-error - doesn't exist yet. generated by Rollup
import { routes, fallback } from 'MANIFEST';
import { Router } from './router.js';
import { Renderer } from './renderer.js';
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/client/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CSRComponent, CSRPage, CSRRoute, NormalizedLoadOutput } from 'types/internal';
import { CSRComponent, CSRRoute, NormalizedLoadOutput } from 'types/internal';
import { Page } from 'types/page';

export type NavigationInfo = {
Expand All @@ -10,7 +10,7 @@ export type NavigationInfo = {
};

export type NavigationCandidate = {
route: CSRPage;
route: CSRRoute;
info: NavigationInfo;
};

Expand Down
4 changes: 2 additions & 2 deletions packages/kit/test/apps/basics/src/routes/routing/_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ export default function (test, is_dev) {
test(
'does not attempt client-side navigation to server routes',
'/routing',
async ({ page, clicknav }) => {
await clicknav('[href="/routing/ambiguous/ok.json"]');
async ({ page }) => {
await page.click('[href="/routing/ambiguous/ok.json"]');
assert.equal(await page.textContent('body'), 'ok');
}
);
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/test/apps/basics/src/routes/routing/index.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h1>Great success!</h1>

<a href="/routing/a">a</a>
<a href="/routing/ambiguous/ok.json">ok</a>
<a href="/routing/ambiguous/ok.json" sveltekit:external>ok</a>
<a href="https://www.google.com">elsewhere</a>

<div class='hydrate-test'></div>
<div class="hydrate-test" />
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function (test) {
assert.equal(await page.textContent('h1'), 'xyz/abc');
assert.equal(await page.textContent('h2'), 'xyz/abc');

await clicknav('[href="/routing/rest/xyz/abc/qwe/deep.json"]');
await page.click('[href="/routing/rest/xyz/abc/qwe/deep.json"]');
assert.equal(await page.textContent('body'), 'xyz/abc/qwe');
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
<h1>{$page.params.rest}</h1>
<h2>{rest}</h2>

<a href="/routing/rest/xyz/abc/qwe/deep.json">deep</a>
<a href="/routing/rest/xyz/abc/qwe/deep.json" sveltekit:external>deep</a>
<a href="/routing/rest/xyz/abc">back</a>
6 changes: 1 addition & 5 deletions packages/kit/types/internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,7 @@ export interface SSREndpoint {

export type SSRRoute = SSREndpoint | SSRPage;

export type CSRPage = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?];

export type CSREndpoint = [RegExp];

export type CSRRoute = CSREndpoint | CSRPage;
export type CSRRoute = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?];

export interface SSRManifest {
assets: Asset[];
Expand Down

0 comments on commit 91476ca

Please sign in to comment.