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

feat: configure error reporting for prerendered routes #11702

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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/gentle-llamas-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sveltejs/kit": minor
---

feat: configure error reporting when routes marked as prerendable were not prerendered
14 changes: 14 additions & 0 deletions packages/kit/src/core/config/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,20 @@ const options = object(
}
),

handleNotPrerenderedRoutes: validate(
(/** @type {any} */ { message }) => {
throw new Error(
message +
'\nTo suppress or handle this error, implement `handleNotPrerenderedRoutes` in https://svelte.dev/docs/kit/configuration#prerender'
);
},
(input, keypath) => {
if (typeof input === 'function') return input;
if (['fail', 'warn', 'ignore'].includes(input)) return input;
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
}
),

origin: validate('http://sveltekit-prerender', (input, keypath) => {
assert_string(input, keypath);

Expand Down
15 changes: 10 additions & 5 deletions packages/kit/src/core/postbuild/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
}
);

const handle_not_prerendered_route = normalise_error_handler(
log,
config.prerender.handleNotPrerenderedRoutes,
({ routes }) => {
const list = routes.map((id) => ` - ${id}`).join('\n');
return `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee https://svelte.dev/docs/kit/page-options#prerender-troubleshooting for info on how to solve this`;
}
);

const q = queue(config.prerender.concurrency);

/**
Expand Down Expand Up @@ -526,11 +535,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
}

if (not_prerendered.length > 0) {
const list = not_prerendered.map((id) => ` - ${id}`).join('\n');

throw new Error(
`The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee https://svelte.dev/docs/kit/page-options#prerender-troubleshooting for info on how to solve this`
);
handle_not_prerendered_route({ routes: not_prerendered });
}

return { prerendered, prerender_map };
Expand Down
16 changes: 16 additions & 0 deletions packages/kit/src/exports/public.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
PrerenderEntryGeneratorMismatchHandlerValue,
PrerenderHttpErrorHandlerValue,
PrerenderMissingIdHandlerValue,
PrerenderMissingRoutesHandlerValue,
PrerenderOption,
RequestOptions,
RouteSegment
Expand Down Expand Up @@ -642,6 +643,21 @@ export interface KitConfig {
* @since 1.16.0
*/
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
/**
* How to respond when a route is marked as prerenderable but has not been prerendered.
*
* - `'fail'` — fail the build
* - `'ignore'` - silently ignore the failure and continue
* - `'warn'` — continue, but print a warning
* - `(details) => void` — a custom error handler that takes a `details` object with a `routes` property which contains all routes that haven't been prerendered. If you `throw` from this function, the build will fail
*
* The default behavior is to fail the build. This may be undesirable when you know that some of your routes may never be reached under certain
* circumstances such as a CMS not returning data for a specific area, resulting in certain routes never being reached.
*
* @default "fail"
* @since 2.16.0
*/
handleNotPrerenderedRoutes?: PrerenderMissingRoutesHandlerValue;
/**
* The value of `url.origin` during prerendering; useful if it is included in rendered content.
* @default "http://sveltekit-prerender"
Expand Down
9 changes: 9 additions & 0 deletions packages/kit/src/types/private.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,17 @@ export interface PrerenderEntryGeneratorMismatchHandler {
(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;
}

export interface PrerenderEntryMissingRoutesHandler {
(details: { routes: string[]; message: string }): void;
}

export type PrerenderHttpErrorHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderHttpErrorHandler;
export type PrerenderMissingIdHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderMissingIdHandler;
export type PrerenderMissingRoutesHandlerValue =
| 'fail'
| 'warn'
| 'ignore'
| PrerenderEntryMissingRoutesHandler;
export type PrerenderEntryGeneratorMismatchHandlerValue =
| 'fail'
| 'warn'
Expand Down
24 changes: 24 additions & 0 deletions packages/kit/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,21 @@ declare module '@sveltejs/kit' {
* @since 1.16.0
*/
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
/**
* How to respond when a route is marked as prerenderable but has not been prerendered.
*
* - `'fail'` — fail the build
* - `'ignore'` - silently ignore the failure and continue
* - `'warn'` — continue, but print a warning
* - `(details) => void` — a custom error handler that takes a `details` object with a `routes` property which contains all routes that haven't been prerendered. If you `throw` from this function, the build will fail
*
* The default behavior is to fail the build. This may be undesirable when you know that some of your routes may never be reached under certain
* circumstances such as a CMS not returning data for a specific area, resulting in certain routes never being reached.
*
* @default "fail"
* @since 2.16.0
*/
handleNotPrerenderedRoutes?: PrerenderMissingRoutesHandlerValue;
/**
* The value of `url.origin` during prerendering; useful if it is included in rendered content.
* @default "http://sveltekit-prerender"
Expand Down Expand Up @@ -1657,8 +1672,17 @@ declare module '@sveltejs/kit' {
(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;
}

interface PrerenderEntryMissingRoutesHandler {
(details: { routes: string[]; message: string }): void;
}

type PrerenderHttpErrorHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderHttpErrorHandler;
type PrerenderMissingIdHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderMissingIdHandler;
type PrerenderMissingRoutesHandlerValue =
| 'fail'
| 'warn'
| 'ignore'
| PrerenderEntryMissingRoutesHandler;
type PrerenderEntryGeneratorMismatchHandlerValue =
| 'fail'
| 'warn'
Expand Down
Loading