Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[breaking] only route pages on the client-side #2656

Merged
merged 3 commits into from
Oct 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 0 additions & 2 deletions documentation/docs/01-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ The job of this function is to return a `{ status, headers, body }` object repre
- `4xx` — client error
- `5xx` — server error

> For successful responses, SvelteKit will generate 304s automatically.

If the returned `body` is an object, and no `content-type` header is returned, it will automatically be turned into a JSON response. (Don't worry about `$lib`, we'll get to that [later](#modules-$lib).)

> Returning nothing is equivalent to an explicit 404 response.
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/07-a-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ In certain cases, you may wish to disable this behaviour. Adding a `sveltekit:no

### rel=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.
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. Examples of this might be linking to another page on your domain that's not part of your SvelteKit app or linking to an endpoint.

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

Expand Down
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
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
12 changes: 4 additions & 8 deletions packages/kit/test/apps/basics/src/routes/routing/_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,10 @@ 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"]');
assert.equal(await page.textContent('body'), 'ok');
}
);
test('does not attempt client-side navigation to server routes', '/routing', async ({ page }) => {
await page.click('[href="/routing/ambiguous/ok.json"]');
assert.equal(await page.textContent('body'), 'ok');
});

test('allows reserved words as route names', '/routing/const', async ({ page }) => {
assert.equal(await page.textContent('h1'), 'reserved words are okay as routes');
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" rel="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" rel="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