Skip to content

Commit 0800da1

Browse files
fix: Always include root layout/error nodes in manifest (#13522)
Fixes #13518. This optimization doesn't work when an app (or a specific bundle, such as the ones generated for edge functions or when split: true in Vercel) has all prerendered routes. Given that the optimization probably isn't actually saving us much, it's probably not worth it to try to find some convoluted workaround. --------- Co-authored-by: Simon H <[email protected]>
1 parent 6e97d5f commit 0800da1

File tree

18 files changed

+142
-6
lines changed

18 files changed

+142
-6
lines changed

.changeset/long-hounds-listen.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 root layout and error nodes even when apps have only prerendered pages

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
"pnpm": {
3939
"onlyBuiltDependencies": [
4040
"svelte-preprocess",
41-
"workerd"
41+
"workerd",
42+
"esbuild"
4243
]
4344
}
44-
}
45+
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ export function generate_manifest({ build_data, prerendered, relative_path, rout
2727
const reindexed = new Map();
2828
/**
2929
* All nodes actually used in the routes definition (prerendered routes are omitted).
30-
* If `routes` is empty, it means that this manifest is only used for server-side resolution
31-
* and the root layout/error is therefore not needed.
32-
* Else, root layout/error is always included as they are needed for 404 and root errors.
30+
* Root layout/error is always included as they are needed for 404 and root errors.
3331
* @type {Set<any>}
3432
*/
35-
const used_nodes = new Set(routes.length > 0 ? [0, 1] : []);
33+
const used_nodes = new Set([0, 1]);
3634

3735
const server_assets = find_server_assets(build_data, routes);
3836

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/test/errors.json
2+
!/.env
3+
/src/routes/routing/symlink-from
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Please do not edit this app unless you're absolutely sure it's not going to affect the tests.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"extends": "./.svelte-kit/tsconfig.json",
3+
"compilerOptions": {
4+
"allowJs": true,
5+
"checkJs": true,
6+
"esModuleInterop": true,
7+
"forceConsistentCasingInFileNames": true,
8+
"resolveJsonModule": true,
9+
"skipLibCheck": true,
10+
"sourceMap": true,
11+
"strict": true,
12+
"moduleResolution": "bundler"
13+
}
14+
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
15+
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
16+
//
17+
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
18+
// from the referenced tsconfig.json - TypeScript does not merge them in
19+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "test-prerendered-app-error-pages",
3+
"private": true,
4+
"version": "0.0.1",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite dev",
8+
"build": "vite build",
9+
"preview": "vite preview",
10+
"prepare": "svelte-kit sync || echo ''",
11+
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
12+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
13+
"test": "pnpm test:dev && pnpm test:build",
14+
"test:dev": "cross-env DEV=true playwright test",
15+
"test:build": "playwright test"
16+
},
17+
"devDependencies": {
18+
"@sveltejs/kit": "workspace:^",
19+
"@sveltejs/vite-plugin-svelte": "^5.0.1",
20+
"cross-env": "^7.0.3",
21+
"svelte": "^5.2.9",
22+
"svelte-check": "^4.1.1",
23+
"typescript": "^5.5.4",
24+
"vite": "^6.0.11"
25+
}
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { config as default } from '../../utils.js';
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// See https://svelte.dev/docs/kit/types#app.d.ts
2+
// for information about these interfaces
3+
declare global {
4+
namespace App {
5+
// interface Error {}
6+
// interface Locals {}
7+
// interface PageData {}
8+
// interface PageState {}
9+
// interface Platform {}
10+
}
11+
}
12+
13+
export {};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
%sveltekit.head%
8+
</head>
9+
<body data-sveltekit-preload-data="hover">
10+
<div style="display: contents">%sveltekit.body%</div>
11+
</body>
12+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>This is your custom error page.</p>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const prerender = true;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<p>
2+
This app exists to assert that an app with only prerendered routes successfully renders custom
3+
error pages.
4+
</p>
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/** @type {import('@sveltejs/kit').Config} */
2+
const config = {
3+
kit: {}
4+
};
5+
6+
export default config;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from '../../../utils.js';
3+
4+
test.describe.configure({ mode: 'parallel' });
5+
6+
test('renders error page on nonexistent route', async ({ page }) => {
7+
await page.goto('/nonexistent', { wait_for_started: false });
8+
expect(await page.textContent('p')).toBe('This is your custom error page.');
9+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { sveltekit } from '@sveltejs/kit/vite';
2+
import path from 'node:path';
3+
import { defineConfig } from 'vite';
4+
5+
export default defineConfig({
6+
plugins: [sveltekit()],
7+
server: {
8+
fs: {
9+
allow: [path.resolve('../../../src')]
10+
}
11+
}
12+
});

pnpm-lock.yaml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)