// SvelteKit configuration of the inspector page (plan ยง8, phase 1): a static
// site, every page prerendered, no server code, and a Content-Security-Policy
// that keeps the page on its own origin.
import adapter from '@sveltejs/adapter-static';
// The only inline style of the site: the style attribute of SvelteKit's route
// announcer (
, written by `svelte-kit sync` into
// .svelte-kit/generated/root.svelte), allowed by its SHA-256 and nothing else.
// It is the hash of the attribute value for @sveltejs/kit 2.70.3; the build
// check (scripts/check-build.mjs) fails if the bundle holds any other inline
// style, and src/app.css hides the announcer anyway in browsers without
// style-src-attr.
const ANNOUNCER_STYLE_HASH = 'sha256-S8qMpvofolR8Mpjy4kQvEm7m1q8clzU4dfDH0AmvZjo=';
/** @type {import('@sveltejs/kit').Config} */
const config = {
compilerOptions: {
runes: true,
},
kit: {
// strict: the build fails if any route is not prerendered.
adapter: adapter({ strict: true }),
// Prerendered pages get the policy as , the first element
// of . In 'hash' mode SvelteKit adds the SHA-256 of each inline
// script it writes (the hydration bootstrap) to script-src; the styles are
// external files (inlineStyleThreshold stays 0), so style-src needs no
// hash, and style-src-attr allows the announcer's style attribute alone.
// Nonces cannot work in prerendered HTML. The fixtures are fetched
// from the same origin; the only other origins the page may reach are
// the public relays of drand, when the person asks for the release of a
// round (src/lib/inspector/drand.ts, as the CLI of the reference).
csp: {
mode: 'hash',
directives: {
'default-src': ['self'],
'script-src': ['self'],
'style-src': ['self'],
'style-src-attr': ['unsafe-hashes', ANNOUNCER_STYLE_HASH],
'img-src': ['self'],
'font-src': ['self'],
'connect-src': ['self', 'https://api.drand.sh', 'https://api2.drand.sh', 'https://api3.drand.sh'],
'manifest-src': ['self'],
'frame-src': ['none'],
'worker-src': ['none'],
'object-src': ['none'],
'base-uri': ['none'],
'form-action': ['none'],
},
},
prerender: {
handleHttpError: 'fail',
handleMissingId: 'fail',
handleUnseenRoutes: 'fail',
},
typescript: {
// The generated tsconfig covers src/ and vite.config.ts; the vitest
// configuration is type-checked as well.
config(tsconfig) {
tsconfig.include.push('../vitest.config.ts');
},
},
},
};
export default config;