Skip to content

Commit dd22fde

Browse files
authored
Fail on 500s during prerendering (#295)
* make prerendering errors easier to see * externalise shiki. unfortunately this means installing it to apps/svelte.dev * fixes * fix * fixes * various fixes * fail build if page 500s when prerendering * lint * ok FINALLY
1 parent 599677a commit dd22fde

File tree

12 files changed

+68
-24
lines changed

12 files changed

+68
-24
lines changed

apps/svelte.dev/content/docs/kit/10-getting-started/10-introduction.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ In short, Svelte is a way of writing user interface components — like a naviga
2222

2323
Svelte renders UI components. You can compose these components and render an entire page with just Svelte, but you need more than just Svelte to write an entire app.
2424

25-
SvelteKit helps you build web apps while following modern best practices and providing solutions to common development challenges. It offers everything from basic functionalities — like a [router](glossary#routing) that updates your UI when a link is clicked — to more advanced capabilities. Its extensive list of features includes [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations) to load only the minimal required code; [offline support](service-workers); [preloading](link-options#data-sveltekit-preload-data) pages before user navigation; [configurable rendering](page-options) to handle different parts of your app on the server via [SSR](glossary#ssr), in the browser through [client-side rendering](glossary#csr), or at build-time with [prerendering](glossary#prerendering); [image optimization](images); and much more. Building an app with all the modern best practices is fiendishly complicated, but SvelteKit does all the boring stuff for you so that you can get on with the creative part.
25+
SvelteKit helps you build web apps while following modern best practices and providing solutions to common development challenges. It offers everything from basic functionalities — like a [router](glossary#Routing) that updates your UI when a link is clicked — to more advanced capabilities. Its extensive list of features includes [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations) to load only the minimal required code; [offline support](service-workers); [preloading](link-options#data-sveltekit-preload-data) pages before user navigation; [configurable rendering](page-options) to handle different parts of your app on the server via [SSR](glossary#SSR), in the browser through [client-side rendering](glossary#CSR), or at build-time with [prerendering](glossary#Prerendering); [image optimization](images); and much more. Building an app with all the modern best practices is fiendishly complicated, but SvelteKit does all the boring stuff for you so that you can get on with the creative part.
2626

2727
It reflects changes to your code in the browser instantly to provide a lightning-fast and feature-rich development experience by leveraging [Vite](https://vitejs.dev/) with a [Svelte plugin](https://github.com/sveltejs/vite-plugin-svelte) to do [Hot Module Replacement (HMR)](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#hot).

apps/svelte.dev/content/docs/kit/25-build-and-deploy/90-adapter-vercel.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,7 @@ Vercel supports [Incremental Static Regeneration](https://vercel.com/docs/increm
9494
To add ISR to a route, include the `isr` property in your `config` object:
9595

9696
```js
97-
/// file: blog/[slug]/+page.server.js
98-
// @filename: ambient.d.ts
99-
declare module '$env/static/private' {
100-
export const BYPASS_TOKEN: string;
101-
}
102-
103-
// @filename: index.js
104-
// ---cut---
97+
// @errors: 2664
10598
import { BYPASS_TOKEN } from '$env/static/private';
10699

107100
export const config = {

apps/svelte.dev/content/docs/kit/40-best-practices/20-seo.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ export async function handle({ event, resolve }) {
110110
To prevent shipping any unused CSS as a result of transforming the page to amp, we can use [`dropcss`](https://www.npmjs.com/package/dropcss):
111111

112112
```js
113+
// @filename: ambient.d.ts
114+
declare module 'dropcss';
115+
116+
// @filename: index.js
117+
// ---cut---
113118
/// file: src/hooks.server.js
114119
// @errors: 2307
115120
import * as amp from '@sveltejs/amp';

apps/svelte.dev/content/docs/kit/98-reference/[email protected]

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ async function first({ event, resolve }) {
3434
preload: () => {
3535
// this one wins as it's the first defined in the chain
3636
console.log('first preload');
37+
return true;
3738
}
3839
});
3940
console.log('first post-processing');
@@ -50,10 +51,12 @@ async function second({ event, resolve }) {
5051
},
5152
preload: () => {
5253
console.log('second preload');
54+
return true;
5355
},
5456
filterSerializedResponseHeaders: () => {
5557
// this one wins as it's the first defined in the chain
56-
console.log('second filterSerializedResponseHeaders');
58+
console.log('second filterSerializedResponseHeaders');
59+
return true;
5760
}
5861
});
5962
console.log('second post-processing');

apps/svelte.dev/content/docs/kit/98-reference/20-$app-paths.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ Populate a route ID with params to resolve a pathname.
5151

5252
```js
5353
// @errors: 7031
54+
import { resolveRoute } from '$app/paths';
55+
5456
resolveRoute(
5557
`/blog/[slug]/[...somethingElse]`,
5658
{

apps/svelte.dev/content/docs/svelte/05-misc/02-testing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export default config;
208208
You can now start writing tests. These are totally unaware of Svelte as a framework, so you mainly interact with the DOM and write assertions.
209209

210210
```js
211+
// @errors: 2307 7031
211212
/// file: tests/hello-world.spec.js
212213
import { expect, test } from '@playwright/test';
213214

apps/svelte.dev/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"@replit/codemirror-lang-svelte": "^6.0.0",
3535
"@replit/codemirror-vim": "^6.0.14",
3636
"@rich_harris/svelte-split-pane": "^1.1.3",
37+
"@shikijs/twoslash": "^1.22.0",
38+
"@sveltejs/amp": "^1.1.3",
3739
"@sveltejs/repl": "workspace:*",
3840
"@testing-library/dom": "^10.4.0",
3941
"@testing-library/svelte": "^5.2.3",
@@ -54,6 +56,7 @@
5456
"port-authority": "^2.0.1",
5557
"prism-svelte": "^0.5.0",
5658
"prismjs": "^1.29.0",
59+
"shiki": "^1.22.0",
5760
"topojson-client": "^3.1.0",
5861
"vitest": "^2.1.2",
5962
"ws": "^8.13.0",

apps/svelte.dev/src/routes/tutorial/[slug]/content.server.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// @ts-expect-error has no types
22
import PrismJS from 'prismjs';
3+
import 'prismjs/components/prism-bash.js';
4+
import 'prismjs/components/prism-diff.js';
5+
import 'prismjs/components/prism-typescript.js';
6+
import 'prism-svelte';
37
import { read } from '$app/server';
48
import { index } from '$lib/server/content';
59
import { markedTransform } from '@sveltejs/site-kit/markdown';
@@ -172,7 +176,8 @@ const default_renderer: Partial<Renderer> = {
172176
} else {
173177
const plang = languages[lang as keyof typeof languages];
174178
const highlighted = plang
175-
? PrismJS.highlight(source, PrismJS.languages[plang], lang)
179+
? // TODO use shiki here rather than Prism?
180+
PrismJS.highlight(source, PrismJS.languages[plang], lang)
176181
: escape_html(source);
177182

178183
html += `<pre class='language-${plang}'><code>${highlighted}</code></pre>`;

apps/svelte.dev/svelte.config.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,23 @@ const config = {
88
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
99
adapter: adapter(),
1010
prerender: {
11-
// TODO remporary while not all docs are migrated
12-
handleHttpError({ path }) {
13-
return path === '/docs/service-workers' || path === '/docs/server-only-modules'
14-
? 'warn'
15-
: 'fail';
11+
handleHttpError(error) {
12+
if (error.status === 500) {
13+
throw new Error(error.message);
14+
}
15+
16+
// TODO fail the build
17+
console.error(`404 ${error.path}`);
1618
},
17-
handleMissingId: 'warn'
19+
handleMissingId(warning) {
20+
if (warning.id.startsWith('H4sIA')) {
21+
// playground link — do nothing
22+
return;
23+
}
24+
25+
// TODO fail the build
26+
console.warn(`${warning.path}#${warning.id}: ${warning.referrers.join(', ')}`);
27+
}
1828
}
1929
}
2030
};

apps/svelte.dev/vite.config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ const config: UserConfig = {
6969
optimizeDeps: {
7070
exclude: ['@sveltejs/site-kit', '@sveltejs/repl', '@rollup/browser']
7171
},
72-
ssr: { noExternal: ['@sveltejs/site-kit', '@sveltejs/repl'] }
72+
ssr: {
73+
noExternal: ['@sveltejs/site-kit', '@sveltejs/repl'],
74+
external: ['shiki', '@shikijs/twoslash']
75+
}
7376
};
7477

7578
export default config;

packages/site-kit/src/lib/markdown/renderer.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,13 @@ async function syntax_highlight({
709709
theme
710710
})
711711
);
712-
} else if (/^(js|ts)/.test(language)) {
712+
} else if (/^(js|ts)$/.test(language)) {
713713
try {
714-
const banner = twoslashBanner?.(filename, source, language, options);
714+
let banner = twoslashBanner?.(filename, source, language, options);
715715

716716
if (banner) {
717+
banner = '// @filename: injected.d.ts\n' + banner;
718+
717719
if (source.includes('// @filename:')) {
718720
source = source.replace('// @filename:', `${banner}\n\n// @filename:`);
719721
} else {
@@ -738,10 +740,9 @@ async function syntax_highlight({
738740
]
739741
});
740742
} catch (e) {
741-
console.error(`Error compiling snippet in ${filename}`);
742-
// @ts-ignore
743-
console.error(e.code);
744-
throw e;
743+
console.error((e as Error).message);
744+
console.warn(source);
745+
throw new Error(`Error compiling snippet in ${filename}`);
745746
}
746747

747748
html = replace_blank_lines(html);

pnpm-lock.yaml

Lines changed: 18 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)