Skip to content

Commit 88b7823

Browse files
committed
[fix] more info about prerendering errors
Helps with #7183 and #7244
1 parent 9cfa964 commit 88b7823

File tree

7 files changed

+40
-11
lines changed

7 files changed

+40
-11
lines changed

.changeset/tame-bats-tell.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/adapter-static': patch
3+
'@sveltejs/kit': patch
4+
---
5+
6+
[fix] more info about prerendering errors

documentation/docs/13-page-options.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ Note that this will disable client-side routing for any navigation from this pag
7272

7373
#### Troubleshooting
7474

75-
If you encounter an error like 'The following routes were marked as prerenderable, but were not prerendered' it's because the route in question (or a parent layout, if it's a page) has `export const prerender = true` but the page wasn't actually prerendered.
75+
If you encounter an error like 'The following routes were marked as prerenderable, but were not prerendered' it's because the route in question (or a parent layout, if it's a page) has `export const prerender = true` but the page wasn't actually prerendered (because they were not reached by the prerendering crawler).
7676

7777
Since these routes cannot be dynamically server-rendered, this will cause errors when people try to access the route in question. There are two ways to fix it:
7878

79-
* Ensure that SvelteKit can find the route by following links from [`config.kit.prerender.entries`](/docs/configuration#prerender). The pages containing the links (e.g. your `/` page) must _themselves_ be prerenderable, or they will be ignored
79+
* Ensure that SvelteKit can find the route by following links from [`config.kit.prerender.entries`](/docs/configuration#prerender). Add links to dynamic routes (i.e. pages with `[parameters]` ) to this option if they are not found through crawling the other entry points, else they are not prerendered because SvelteKit doesn't know what value the parameters should have. The pages containing the links (e.g. your `/` page) must _themselves_ be prerenderable, or they will be ignored.
8080
* Change `export const prerender = true` to `export const prerender = 'auto'`. Routes with `'auto'` can be dynamically server rendered
8181

82+
If you are using `@sveltejs/adapter-static`, _all_ pages (and endpoints, if any) must be prerendered, else you need to use a different adapter.
83+
8284
### ssr
8385

8486
Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's hydrated. If you set `ssr` to `false`, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server, but in most situations it's not recommended ([see appendix](/docs/appendix#ssr)).

documentation/docs/16-configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ See [Prerendering](/docs/page-options#prerender). An object containing zero or m
252252
- `concurrency` — how many pages can be prerendered simultaneously. JS is single-threaded, but in cases where prerendering performance is network-bound (for example loading content from a remote CMS) this can speed things up by processing other tasks while waiting on the network response
253253
- `crawl` — determines whether SvelteKit should find pages to prerender by following links from the seed page(s)
254254
- `enabled` — set to `false` to disable prerendering altogether
255-
- `entries` — an array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]` )
255+
- `entries` — an array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]` ), because SvelteKit doesn't know what value the parameters should have
256256
- `onError`
257257

258258
- `'fail'` — (default) fails the build when a routing error is encountered when following a link

packages/adapter-static/index.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,27 @@ export default function (options) {
2626

2727
if (dynamic_routes.length > 0) {
2828
const prefix = path.relative('.', builder.config.kit.files.routes);
29+
const has_routes_with_params = dynamic_routes.some((route) => route.includes('['));
30+
const config_option =
31+
JSON.stringify(builder.config.kit.prerender.entries) === '["*"]' &&
32+
!has_routes_with_params
33+
? ''
34+
: ` - adjust the \`prerender.entries\` config option ${
35+
has_routes_with_params
36+
? `(routes with parameters are not part of entry points by default)`
37+
: ''
38+
} — see https://kit.svelte.dev/docs/configuration#prerender for more info\n`;
2939
builder.log.error(
30-
`@sveltejs/adapter-static: all routes must be fully prerenderable (unless using the 'fallback' option — see https://github.com/sveltejs/kit/tree/master/packages/adapter-static#spa-mode). Try adding \`export const prerender = true\` to your root +layout.js/.ts file — see https://kit.svelte.dev/docs/page-options#prerender for more details`
31-
);
32-
builder.log.error(
33-
dynamic_routes.map((id) => ` - ${path.posix.join(prefix, id)}`).join('\n')
40+
`@sveltejs/adapter-static: all routes must be fully prerenderable, but found the following routes that are dynamic:
41+
${dynamic_routes.map((id) => ` - ${path.posix.join(prefix, id)}`).join('\n')}
42+
43+
You have the following options:
44+
- set the 'fallback' option — see https://github.com/sveltejs/kit/tree/master/packages/adapter-static#spa-mode for more info
45+
- add \`export const prerender = true\` to your root \`+layout.js/.ts\` or \`+layout.server.js/.ts\` file. This will try to prerender all pages.
46+
- add \`export const prerender = true\` to your \`+server.js/ts\` files (if any) that are not called through pages (else these are not prerendered).
47+
${config_option}
48+
If this doesn't help, you may need to use a different adapter. @sveltejs/adapter-static can only be used for sites that don't need a backend (i.e. a static file server is enough).
49+
See https://kit.svelte.dev/docs/page-options#prerender for more details`
3450
);
3551
throw new Error('Encountered dynamic routes');
3652
}

packages/kit/src/core/prerender/prerender.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,9 @@ export async function prerender() {
431431

432432
if (not_prerendered.length > 0) {
433433
throw new Error(
434-
`The following routes were marked as prerenderable, but were not prerendered:\n${not_prerendered.map(
434+
`The following routes were marked as prerenderable, but were not prerendered, because they were not found while crawling your app:\n${not_prerendered.map(
435435
(id) => ` - ${id}`
436-
)}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for more info`
436+
)}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for more info and how to solve this`
437437
);
438438
}
439439

packages/kit/src/utils/filesystem.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ export function mkdirp(dir) {
66
try {
77
fs.mkdirSync(dir, { recursive: true });
88
} catch (/** @type {any} */ e) {
9-
if (e.code === 'EEXIST') return;
9+
if (e.code === 'EEXIST') {
10+
if (!fs.statSync(dir).isDirectory()) {
11+
throw new Error(`Cannot create directory ${dir}, a file already exists at this position`);
12+
}
13+
return;
14+
}
1015
throw e;
1116
}
1217
}

packages/kit/test/build-errors/prerender.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ test('prerenderable routes must be prerendered', () => {
1111
stdio: 'pipe',
1212
timeout: 15000
1313
}),
14-
/The following routes were marked as prerenderable, but were not prerendered:\r?\n - \[x\]/gs
14+
/The following routes were marked as prerenderable, but were not prerendered, because they were not found while crawling your app:\r?\n - \[x\]/gs
1515
);
1616
});
1717

0 commit comments

Comments
 (0)