diff --git a/.changeset/gorgeous-beans-glow.md b/.changeset/gorgeous-beans-glow.md
new file mode 100644
index 000000000000..6ef3bba3be17
--- /dev/null
+++ b/.changeset/gorgeous-beans-glow.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[breaking] expose entire config to adapters, rather than just appDir and trailingSlash
diff --git a/.changeset/khaki-dolls-cough.md b/.changeset/khaki-dolls-cough.md
new file mode 100644
index 000000000000..2e85df32d862
--- /dev/null
+++ b/.changeset/khaki-dolls-cough.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[breaking] replace builder.prerender() with builder.writePrerendered() and builder.prerendered
diff --git a/.changeset/large-berries-exercise.md b/.changeset/large-berries-exercise.md
new file mode 100644
index 000000000000..4e72f454eb83
--- /dev/null
+++ b/.changeset/large-berries-exercise.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[breaking] prerender pages during build, regardless of adapter
diff --git a/.changeset/modern-toys-appear.md b/.changeset/modern-toys-appear.md
new file mode 100644
index 000000000000..3ca8cd419e78
--- /dev/null
+++ b/.changeset/modern-toys-appear.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Add config.kit.prerender.default option
diff --git a/.changeset/nine-walls-shake.md b/.changeset/nine-walls-shake.md
new file mode 100644
index 000000000000..f222efb4a0bf
--- /dev/null
+++ b/.changeset/nine-walls-shake.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Use prerendered pages in svelte-kit preview
diff --git a/.changeset/shaggy-days-cheat.md b/.changeset/shaggy-days-cheat.md
new file mode 100644
index 000000000000..bb6f4b5a8d93
--- /dev/null
+++ b/.changeset/shaggy-days-cheat.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Make prerendered paths available to service workers
diff --git a/.prettierrc b/.prettierrc
index 5e006e35333d..ff4587b4d023 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -13,7 +13,7 @@
{
"files": [
"packages/kit/src/packaging/test/fixtures/**/expected/**/*",
- "packages/kit/src/core/adapt/prerender/fixtures/**/*"
+ "packages/kit/src/core/build/prerender/fixtures/**/*"
],
"options": {
"requirePragma": true
diff --git a/documentation/docs/09-adapters.md b/documentation/docs/09-adapters.md
index 07957bf1ebae..d17df5ffb7a5 100644
--- a/documentation/docs/09-adapters.md
+++ b/documentation/docs/09-adapters.md
@@ -99,7 +99,7 @@ The types for `Adapter` and its parameters are available in [types/config.d.ts](
Within the `adapt` method, there are a number of things that an adapter should do:
- Clear out the build directory
-- Call `builder.prerender({ dest })` to prerender pages
+- Write SvelteKit output with `builder.writeClient`, `builder.writePrerendered`, `builder.writeServer`, and `builder.writeStatic`
- Output code that:
- Imports `App` from `${builder.getServerDirectory()}/app.js`
- Instantiates the app with a manifest generated with `builder.generateManifest({ relativePath })`
diff --git a/documentation/docs/10-page-options.md b/documentation/docs/10-page-options.md
index 12d8398e91e3..77a3a954a3ad 100644
--- a/documentation/docs/10-page-options.md
+++ b/documentation/docs/10-page-options.md
@@ -38,9 +38,7 @@ Ordinarily, SvelteKit [hydrates](/docs/appendix#hydration) your server-rendered
It's likely that at least some pages of your app can be represented as a simple HTML file generated at build time. These pages can be [_prerendered_](/docs/appendix#prerendering) by your [adapter](/docs/adapters).
-If your entire app is suitable for prerendering, you could use [`adapter-static`](https://github.com/sveltejs/kit/tree/master/packages/adapter-static), which will generate HTML files for every page, plus additional files that are requested by `load` functions in those pages.
-
-In many cases, you'll only want to prerender specific pages in your app. You'll need to annotate these pages:
+Prerendering happens automatically for any page with the `prerender` annotation:
```html
```
+Alternatively, you can set [`confit.kit.prerender.default`](/docs/configuration#prerender) to `true` and prerender everything except pages that are explicitly marked as _not_ prerenderable:
+
+```html
+
+```
+
+> If your entire app is suitable for prerendering, you can use [`adapter-static`](https://github.com/sveltejs/kit/tree/master/packages/adapter-static), which will output files suitable for use with any static webserver.
+
The prerenderer will start at the root of your app and generate HTML for any prerenderable pages it finds. Each page is scanned for `` elements that point to other pages that are candidates for prerendering — because of this, you generally don't need to specify which pages should be accessed. If you _do_ need to specify which pages should be accessed by the prerenderer, you can do so with the `entries` option in the [prerender configuration](/docs/configuration#prerender).
#### When not to prerender
diff --git a/documentation/docs/13-configuration.md b/documentation/docs/13-configuration.md
index 154a6e15060f..3a0d47e27cc8 100644
--- a/documentation/docs/13-configuration.md
+++ b/documentation/docs/13-configuration.md
@@ -224,6 +224,7 @@ See [Prerendering](/docs/page-options#prerender). An object containing zero or m
- `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
- `crawl` — determines whether SvelteKit should find pages to prerender by following links from the seed page(s)
+- `default` — set to `true` to prerender every page without `export const prerender = false`
- `enabled` — set to `false` to disable prerendering altogether
- `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]` )
- `onError`
diff --git a/packages/adapter-cloudflare-workers/index.js b/packages/adapter-cloudflare-workers/index.js
index 745bbf006b11..c4b6aa4c69ba 100644
--- a/packages/adapter-cloudflare-workers/index.js
+++ b/packages/adapter-cloudflare-workers/index.js
@@ -25,9 +25,6 @@ export default function () {
builder.rimraf(bucket);
builder.rimraf(entrypoint);
- builder.log.info('Prerendering static pages...');
- const prerendered = await builder.prerender({ dest: bucket });
-
builder.log.info('Installing worker dependencies...');
builder.copy(`${files}/_package.json`, `${tmp}/package.json`);
@@ -49,7 +46,7 @@ export default function () {
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({
relativePath
- })};\n\nexport const prerendered = new Set(${JSON.stringify(prerendered.paths)});\n`
+ })};\n\nexport const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});\n`
);
await esbuild.build({
@@ -65,6 +62,7 @@ export default function () {
builder.log.minor('Copying assets...');
builder.writeClient(bucket);
builder.writeStatic(bucket);
+ builder.writePrerendered(bucket);
}
};
}
diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js
index 9af0566f94ce..ea3005e08da5 100644
--- a/packages/adapter-cloudflare/index.js
+++ b/packages/adapter-cloudflare/index.js
@@ -18,8 +18,7 @@ export default function (options = {}) {
builder.writeStatic(dest);
builder.writeClient(dest);
-
- const prerendered = await builder.prerender({ dest });
+ builder.writePrerendered(dest);
const relativePath = posix.relative(tmp, builder.getServerDirectory());
@@ -27,7 +26,7 @@ export default function (options = {}) {
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({
relativePath
- })};\n\nexport const prerendered = new Set(${JSON.stringify(prerendered.paths)});\n`
+ })};\n\nexport const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});\n`
);
builder.copy(`${files}/worker.js`, `${tmp}/_worker.js`, {
diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js
index a37894a88c75..330071470d6b 100644
--- a/packages/adapter-netlify/index.js
+++ b/packages/adapter-netlify/index.js
@@ -36,11 +36,6 @@ export default function ({ split = false } = {}) {
builder.log.minor(`Publishing to "${publish}"`);
- builder.log.minor('Prerendering static pages...');
- await builder.prerender({
- dest: publish
- });
-
builder.writeServer('.netlify/server');
// for esbuild, use ESM
@@ -127,6 +122,7 @@ export default function ({ split = false } = {}) {
builder.log.minor('Copying assets...');
builder.writeStatic(publish);
builder.writeClient(publish);
+ builder.writePrerendered(publish);
builder.log.minor('Writing redirects...');
const redirect_file = join(publish, '_redirects');
@@ -138,7 +134,7 @@ export default function ({ split = false } = {}) {
builder.copy('_headers', headers_file);
appendFileSync(
headers_file,
- `\n\n/${builder.appDir}/*\n cache-control: public\n cache-control: immutable\n cache-control: max-age=31536000\n`
+ `\n\n/${builder.config.kit.appDir}/*\n cache-control: public\n cache-control: immutable\n cache-control: max-age=31536000\n`
);
}
};
diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js
index 8fd7059511d8..fc302b17a978 100644
--- a/packages/adapter-node/index.js
+++ b/packages/adapter-node/index.js
@@ -34,11 +34,7 @@ export default function ({
builder.writeClient(`${out}/client`);
builder.writeServer(`${out}/server`);
builder.writeStatic(`${out}/static`);
-
- builder.log.minor('Prerendering static pages');
- await builder.prerender({
- dest: `${out}/prerendered`
- });
+ builder.writePrerendered(`${out}/prerendered`);
writeFileSync(
`${out}/manifest.js`,
diff --git a/packages/adapter-static/index.js b/packages/adapter-static/index.js
index 58483e74bc46..cb5a05d1d780 100644
--- a/packages/adapter-static/index.js
+++ b/packages/adapter-static/index.js
@@ -12,17 +12,18 @@ export default function ({ pages = 'build', assets = pages, fallback, precompres
name: '@sveltejs/adapter-static',
async adapt(builder) {
+ if (!fallback && !builder.config.kit.prerender.default) {
+ builder.log.warn(
+ 'You should set `config.kit.prerender.default` to `true` if no fallback is specified'
+ );
+ }
+
builder.rimraf(assets);
builder.rimraf(pages);
builder.writeStatic(assets);
builder.writeClient(assets);
-
- await builder.prerender({
- fallback,
- all: !fallback,
- dest: pages
- });
+ builder.writePrerendered(pages, { fallback });
if (precompress) {
if (pages === assets) {
diff --git a/packages/adapter-static/test/apps/prerendered/svelte.config.js b/packages/adapter-static/test/apps/prerendered/svelte.config.js
index 20cd2b3ff5b8..b2c66c3eeb9e 100644
--- a/packages/adapter-static/test/apps/prerendered/svelte.config.js
+++ b/packages/adapter-static/test/apps/prerendered/svelte.config.js
@@ -3,7 +3,11 @@ import adapter from '../../../index.js';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
- adapter: adapter()
+ adapter: adapter(),
+
+ prerender: {
+ default: true
+ }
}
};
diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js
index d9c69de89d2e..67c29e4a60b1 100644
--- a/packages/adapter-vercel/index.js
+++ b/packages/adapter-vercel/index.js
@@ -100,12 +100,6 @@ export default function ({ external = [] } = {}) {
lambda: `${dir}/functions/node/render`
};
- builder.log.minor('Prerendering static pages...');
-
- const prerendered = await builder.prerender({
- dest: `${dir}/static`
- });
-
builder.log.minor('Generating serverless function...');
const relativePath = posix.relative(tmp, builder.getServerDirectory());
@@ -139,32 +133,36 @@ export default function ({ external = [] } = {}) {
builder.writeStatic(dirs.static);
builder.writeClient(dirs.static);
+ builder.writePrerendered(dirs.static);
builder.log.minor('Writing routes...');
builder.mkdirp(`${dir}/config`);
- const prerendered_pages = Array.from(prerendered.pages, ([src, page]) => ({
+ const prerendered_pages = Array.from(builder.prerendered.pages, ([src, page]) => ({
src,
dest: page.file
}));
- const prerendered_redirects = Array.from(prerendered.redirects, ([src, redirect]) => ({
- src,
- headers: {
- Location: redirect.location
- },
- status: redirect.status
- }));
+ const prerendered_redirects = Array.from(
+ builder.prerendered.redirects,
+ ([src, redirect]) => ({
+ src,
+ headers: {
+ Location: redirect.location
+ },
+ status: redirect.status
+ })
+ );
writeFileSync(
`${dir}/config/routes.json`,
JSON.stringify([
- ...redirects[builder.trailingSlash],
+ ...redirects[builder.config.kit.trailingSlash],
...prerendered_pages,
...prerendered_redirects,
{
- src: `/${builder.appDir}/.+`,
+ src: `/${builder.config.kit.appDir}/.+`,
headers: {
'cache-control': 'public, immutable, max-age=31536000'
}
diff --git a/packages/kit/src/cli.js b/packages/kit/src/cli.js
index 43328e1077a4..d374f6156254 100755
--- a/packages/kit/src/cli.js
+++ b/packages/kit/src/cli.js
@@ -5,6 +5,7 @@ import * as ports from 'port-authority';
import { load_config } from './core/config/index.js';
import { networkInterfaces, release } from 'os';
import { coalesce_to_error } from './utils/error.js';
+import { logger } from './core/utils.js';
/** @param {unknown} e */
function handle_error(e) {
@@ -91,8 +92,10 @@ prog
process.env.NODE_ENV = process.env.NODE_ENV || 'production';
const config = await load_config();
+ const log = logger({ verbose });
+
const { build } = await import('./core/build/index.js');
- const build_data = await build(config);
+ const { build_data, prerendered } = await build(config, { log });
console.log(
`\nRun ${colors.bold().cyan('npm run preview')} to preview your production build locally.`
@@ -100,7 +103,7 @@ prog
if (config.kit.adapter) {
const { adapt } = await import('./core/adapt/index.js');
- await adapt(config, build_data, { verbose });
+ await adapt(config, build_data, prerendered, { log });
// this is necessary to close any open db connections, etc
process.exit(0);
diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js
index 2a21be674947..6c1afb0140ef 100644
--- a/packages/kit/src/core/adapt/builder.js
+++ b/packages/kit/src/core/adapt/builder.js
@@ -1,25 +1,22 @@
import { copy, rimraf, mkdirp } from '../../utils/filesystem.js';
-import { prerender } from './prerender/prerender.js';
import { generate_manifest } from '../generate_manifest/index.js';
/**
* @param {{
* config: import('types').ValidatedConfig;
* build_data: import('types').BuildData;
+ * prerendered: import('types').Prerendered;
* log: import('types').Logger;
* }} opts
* @returns {import('types').Builder}
*/
-export function create_builder({ config, build_data, log }) {
+export function create_builder({ config, build_data, prerendered, log }) {
/** @type {Set} */
- let prerendered_paths;
-
- let generated_manifest = false;
+ const prerendered_paths = new Set(prerendered.paths);
/** @param {import('types').RouteData} route */
+ // TODO routes should come pre-filtered
function not_prerendered(route) {
- if (!prerendered_paths) return true;
-
if (route.type === 'page' && route.path) {
return !prerendered_paths.has(route.path);
}
@@ -33,12 +30,10 @@ export function create_builder({ config, build_data, log }) {
mkdirp,
copy,
- appDir: config.kit.appDir,
- trailingSlash: config.kit.trailingSlash,
+ config,
+ prerendered,
createEntries(fn) {
- generated_manifest = true;
-
const { routes } = build_data.manifest_data;
/** @type {import('types').RouteDefinition[]} */
@@ -99,20 +94,24 @@ export function create_builder({ config, build_data, log }) {
if (filtered.size > 0) {
complete({
generateManifest: ({ relativePath, format }) =>
- generate_manifest(build_data, relativePath, Array.from(filtered), format)
+ generate_manifest({
+ build_data,
+ relative_path: relativePath,
+ routes: Array.from(filtered),
+ format
+ })
});
}
}
},
generateManifest: ({ relativePath, format }) => {
- generated_manifest = true;
- return generate_manifest(
+ return generate_manifest({
build_data,
- relativePath,
- build_data.manifest_data.routes.filter(not_prerendered),
+ relative_path: relativePath,
+ routes: build_data.manifest_data.routes.filter(not_prerendered),
format
- );
+ });
},
getBuildDirectory(name) {
@@ -137,6 +136,18 @@ export function create_builder({ config, build_data, log }) {
});
},
+ writePrerendered(dest, { fallback } = {}) {
+ const source = `${config.kit.outDir}/output/prerendered`;
+ const files = [...copy(`${source}/pages`, dest), ...copy(`${source}/dependencies`, dest)];
+
+ if (fallback) {
+ files.push(fallback);
+ copy(`${source}/fallback.html`, `${dest}/${fallback}`);
+ }
+
+ return files;
+ },
+
writeServer(dest) {
return copy(`${config.kit.outDir}/output/server`, dest, {
filter: (file) => file[0] !== '.'
@@ -147,25 +158,11 @@ export function create_builder({ config, build_data, log }) {
return copy(config.kit.files.assets, dest);
},
- async prerender({ all = false, dest, fallback }) {
- if (generated_manifest) {
- throw new Error(
- 'Adapters must call prerender(...) before createEntries(...) or generateManifest(...)'
- );
- }
-
- const prerendered = await prerender({
- out: dest,
- all,
- config,
- build_data,
- fallback,
- log
- });
-
- prerendered_paths = new Set(prerendered.paths);
-
- return prerendered;
+ // @ts-expect-error
+ async prerender() {
+ throw new Error(
+ 'builder.prerender() has been removed. Prerendering now takes place in the build phase — see builder.prerender and builder.writePrerendered'
+ );
}
};
}
diff --git a/packages/kit/src/core/adapt/builder.spec.js b/packages/kit/src/core/adapt/builder.spec.js
index 24370092cbca..2778cff29248 100644
--- a/packages/kit/src/core/adapt/builder.spec.js
+++ b/packages/kit/src/core/adapt/builder.spec.js
@@ -30,6 +30,10 @@ test('copy files', () => {
// @ts-expect-error
build_data: {},
// @ts-expect-error
+ prerendered: {
+ paths: []
+ },
+ // @ts-expect-error
log: {}
});
diff --git a/packages/kit/src/core/adapt/index.js b/packages/kit/src/core/adapt/index.js
index 645b55df7212..25d02039f065 100644
--- a/packages/kit/src/core/adapt/index.js
+++ b/packages/kit/src/core/adapt/index.js
@@ -1,19 +1,18 @@
import colors from 'kleur';
-import { logger } from '../utils.js';
import { create_builder } from './builder.js';
/**
* @param {import('types').ValidatedConfig} config
* @param {import('types').BuildData} build_data
- * @param {{ verbose: boolean }} opts
+ * @param {import('types').Prerendered} prerendered
+ * @param {{ log: import('types').Logger }} opts
*/
-export async function adapt(config, build_data, { verbose }) {
+export async function adapt(config, build_data, prerendered, { log }) {
const { name, adapt } = config.kit.adapter;
console.log(colors.bold().cyan(`\n> Using ${name}`));
- const log = logger({ verbose });
- const builder = create_builder({ config, build_data, log });
+ const builder = create_builder({ config, build_data, prerendered, log });
await adapt(builder);
log.success('done');
diff --git a/packages/kit/src/core/build/build_service_worker.js b/packages/kit/src/core/build/build_service_worker.js
index 965e91459073..4d4158952c48 100644
--- a/packages/kit/src/core/build/build_service_worker.js
+++ b/packages/kit/src/core/build/build_service_worker.js
@@ -2,21 +2,24 @@ import fs from 'fs';
import vite from 'vite';
import { s } from '../../utils/misc.js';
import { deep_merge } from '../../utils/object.js';
+import { normalize_path } from '../../utils/url.js';
import { print_config_conflicts } from '../config/index.js';
/**
* @param {{
* cwd: string;
* assets_base: string;
- * config: import('types').ValidatedConfig
- * manifest_data: import('types').ManifestData
+ * config: import('types').ValidatedConfig;
+ * manifest_data: import('types').ManifestData;
* output_dir: string;
* service_worker_entry_file: string | null;
* }} options
+ * @param {import('types').Prerendered} prerendered
* @param {import('vite').Manifest} client_manifest
*/
export async function build_service_worker(
{ cwd, assets_base, config, manifest_data, output_dir, service_worker_entry_file },
+ prerendered,
client_manifest
) {
// TODO add any assets referenced in template .html file, e.g. favicon?
@@ -49,6 +52,12 @@ export async function build_service_worker(
.map((asset) => `${s(`${config.kit.paths.base}/${asset.file}`)}`)
.join(',\n\t\t\t\t')}
];
+
+ export const prerendered = [
+ ${prerendered.paths
+ .map((path) => s(normalize_path(path, config.kit.trailingSlash)))
+ .join(',\n\t\t\t\t')}
+ ];
`
.replace(/^\t{3}/gm, '')
.trim()
diff --git a/packages/kit/src/core/build/index.js b/packages/kit/src/core/build/index.js
index e9ba0d3c34eb..61def523cc7f 100644
--- a/packages/kit/src/core/build/index.js
+++ b/packages/kit/src/core/build/index.js
@@ -7,12 +7,13 @@ import { generate_manifest } from '../generate_manifest/index.js';
import { build_service_worker } from './build_service_worker.js';
import { build_client } from './build_client.js';
import { build_server } from './build_server.js';
+import { prerender } from './prerender/prerender.js';
/**
* @param {import('types').ValidatedConfig} config
- * @returns {Promise}
+ * @param {{ log: import('types').Logger }} opts
*/
-export async function build(config) {
+export async function build(config, { log }) {
const cwd = process.cwd(); // TODO is this necessary?
const build_dir = path.join(config.kit.outDir, 'build');
@@ -44,28 +45,53 @@ export async function build(config) {
const client = await build_client(options);
const server = await build_server(options, client);
- if (options.service_worker_entry_file) {
- if (config.kit.paths.assets) {
- throw new Error('Cannot use service worker alongside config.kit.paths.assets');
- }
-
- await build_service_worker(options, client.vite_manifest);
- }
-
+ /** @type {import('types').BuildData} */
const build_data = {
app_dir: config.kit.appDir,
manifest_data: options.manifest_data,
service_worker: options.service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable?
client,
- server,
- static: options.manifest_data.assets.map((asset) => posixify(asset.file)),
- entries: options.manifest_data.routes
- .map((route) => (route.type === 'page' ? route.path : ''))
- .filter(Boolean)
+ server
};
- const manifest = `export const manifest = ${generate_manifest(build_data, '.')};\n`;
+ const manifest = `export const manifest = ${generate_manifest({
+ build_data,
+ relative_path: '.',
+ routes: options.manifest_data.routes
+ })};\n`;
fs.writeFileSync(`${output_dir}/server/manifest.js`, manifest);
- return build_data;
+ const static_files = options.manifest_data.assets.map((asset) => posixify(asset.file));
+
+ const files = new Set([
+ ...static_files,
+ ...client.chunks.map((chunk) => `${config.kit.appDir}/${chunk.fileName}`),
+ ...client.assets.map((chunk) => `${config.kit.appDir}/${chunk.fileName}`)
+ ]);
+
+ // TODO is this right?
+ static_files.forEach((file) => {
+ if (file.endsWith('/index.html')) {
+ files.add(file.slice(0, -11));
+ }
+ });
+
+ const prerendered = await prerender({
+ config,
+ entries: options.manifest_data.routes
+ .map((route) => (route.type === 'page' ? route.path : ''))
+ .filter(Boolean),
+ files,
+ log
+ });
+
+ if (options.service_worker_entry_file) {
+ if (config.kit.paths.assets) {
+ throw new Error('Cannot use service worker alongside config.kit.paths.assets');
+ }
+
+ await build_service_worker(options, prerendered, client.vite_manifest);
+ }
+
+ return { build_data, prerendered };
}
diff --git a/packages/kit/src/core/adapt/prerender/crawl.js b/packages/kit/src/core/build/prerender/crawl.js
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/crawl.js
rename to packages/kit/src/core/build/prerender/crawl.js
diff --git a/packages/kit/src/core/adapt/prerender/crawl.spec.js b/packages/kit/src/core/build/prerender/crawl.spec.js
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/crawl.spec.js
rename to packages/kit/src/core/build/prerender/crawl.spec.js
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-href/input.html b/packages/kit/src/core/build/prerender/fixtures/basic-href/input.html
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-href/input.html
rename to packages/kit/src/core/build/prerender/fixtures/basic-href/input.html
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-href/output.json b/packages/kit/src/core/build/prerender/fixtures/basic-href/output.json
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-href/output.json
rename to packages/kit/src/core/build/prerender/fixtures/basic-href/output.json
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-src/input.html b/packages/kit/src/core/build/prerender/fixtures/basic-src/input.html
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-src/input.html
rename to packages/kit/src/core/build/prerender/fixtures/basic-src/input.html
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-src/output.json b/packages/kit/src/core/build/prerender/fixtures/basic-src/output.json
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-src/output.json
rename to packages/kit/src/core/build/prerender/fixtures/basic-src/output.json
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-srcset/input.html b/packages/kit/src/core/build/prerender/fixtures/basic-srcset/input.html
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-srcset/input.html
rename to packages/kit/src/core/build/prerender/fixtures/basic-srcset/input.html
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/basic-srcset/output.json b/packages/kit/src/core/build/prerender/fixtures/basic-srcset/output.json
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/basic-srcset/output.json
rename to packages/kit/src/core/build/prerender/fixtures/basic-srcset/output.json
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/include-rel-external/input.html b/packages/kit/src/core/build/prerender/fixtures/include-rel-external/input.html
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/include-rel-external/input.html
rename to packages/kit/src/core/build/prerender/fixtures/include-rel-external/input.html
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/include-rel-external/output.json b/packages/kit/src/core/build/prerender/fixtures/include-rel-external/output.json
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/include-rel-external/output.json
rename to packages/kit/src/core/build/prerender/fixtures/include-rel-external/output.json
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/unquoted-attributes/input.html b/packages/kit/src/core/build/prerender/fixtures/unquoted-attributes/input.html
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/unquoted-attributes/input.html
rename to packages/kit/src/core/build/prerender/fixtures/unquoted-attributes/input.html
diff --git a/packages/kit/src/core/adapt/prerender/fixtures/unquoted-attributes/output.json b/packages/kit/src/core/build/prerender/fixtures/unquoted-attributes/output.json
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/fixtures/unquoted-attributes/output.json
rename to packages/kit/src/core/build/prerender/fixtures/unquoted-attributes/output.json
diff --git a/packages/kit/src/core/adapt/prerender/prerender.js b/packages/kit/src/core/build/prerender/prerender.js
similarity index 85%
rename from packages/kit/src/core/adapt/prerender/prerender.js
rename to packages/kit/src/core/build/prerender/prerender.js
index 9cdab9b9094d..c21e4da89635 100644
--- a/packages/kit/src/core/adapt/prerender/prerender.js
+++ b/packages/kit/src/core/build/prerender/prerender.js
@@ -40,15 +40,13 @@ const REDIRECT = 3;
/**
* @param {{
- * out: string;
- * log: Logger;
* config: import('types').ValidatedConfig;
- * build_data: import('types').BuildData;
- * fallback?: string;
- * all: boolean; // disregard `export const prerender = true`
+ * entries: string[];
+ * files: Set;
+ * log: Logger;
* }} opts
*/
-export async function prerender({ out, log, config, build_data, fallback, all }) {
+export async function prerender({ config, entries, files, log }) {
/** @type {import('types').Prerendered} */
const prerendered = {
pages: new Map(),
@@ -57,7 +55,7 @@ export async function prerender({ out, log, config, build_data, fallback, all })
paths: []
};
- if (!config.kit.prerender.enabled && !fallback) {
+ if (!config.kit.prerender.enabled) {
return prerendered;
}
@@ -79,18 +77,6 @@ export async function prerender({ out, log, config, build_data, fallback, all })
const error = normalise_error_handler(log, config.kit.prerender.onError);
- const files = new Set([
- ...build_data.static,
- ...build_data.client.chunks.map((chunk) => `${config.kit.appDir}/${chunk.fileName}`),
- ...build_data.client.assets.map((chunk) => `${config.kit.appDir}/${chunk.fileName}`)
- ]);
-
- build_data.static.forEach((file) => {
- if (file.endsWith('/index.html')) {
- files.add(file.slice(0, -11));
- }
- });
-
const q = queue(config.kit.prerender.concurrency);
/**
@@ -145,14 +131,14 @@ export async function prerender({ out, log, config, build_data, fallback, all })
const response = await server.respond(new Request(`http://sveltekit-prerender${encoded}`), {
prerender: {
- all,
+ default: config.kit.prerender.default,
dependencies
}
});
const text = await response.text();
- save(response, text, decoded, encoded, referrer, 'linked');
+ save('pages', response, text, decoded, encoded, referrer, 'linked');
for (const [dependency_path, result] of dependencies) {
// this seems circuitous, but using new URL allows us to not care
@@ -162,6 +148,7 @@ export async function prerender({ out, log, config, build_data, fallback, all })
const body = result.body ?? new Uint8Array(await result.response.arrayBuffer());
save(
+ 'dependencies',
result.response,
body,
decoded_dependency_path,
@@ -191,6 +178,7 @@ export async function prerender({ out, log, config, build_data, fallback, all })
}
/**
+ * @param {'pages' | 'dependencies'} category
* @param {Response} response
* @param {string | Uint8Array} body
* @param {string} decoded
@@ -198,13 +186,13 @@ export async function prerender({ out, log, config, build_data, fallback, all })
* @param {string | null} referrer
* @param {'linked' | 'fetched'} referenceType
*/
- function save(response, body, decoded, encoded, referrer, referenceType) {
+ function save(category, response, body, decoded, encoded, referrer, referenceType) {
const response_type = Math.floor(response.status / 100);
const type = /** @type {string} */ (response.headers.get('content-type'));
const is_html = response_type === REDIRECT || type === 'text/html';
const file = output_filename(decoded, is_html);
- const dest = `${out}/${file}`;
+ const dest = `${config.kit.outDir}/output/prerendered/${category}/${file}`;
if (written.has(file)) return;
written.add(file);
@@ -268,7 +256,7 @@ export async function prerender({ out, log, config, build_data, fallback, all })
if (config.kit.prerender.enabled) {
for (const entry of config.kit.prerender.entries) {
if (entry === '*') {
- for (const entry of build_data.entries) {
+ for (const entry of entries) {
enqueue(null, normalize_path(config.kit.paths.base + entry, config.kit.trailingSlash)); // TODO can we pre-normalize these?
}
} else {
@@ -279,19 +267,17 @@ export async function prerender({ out, log, config, build_data, fallback, all })
await q.done();
}
- if (fallback) {
- const rendered = await server.respond(new Request('http://sveltekit-prerender/[fallback]'), {
- prerender: {
- fallback,
- all: false,
- dependencies: new Map()
- }
- });
+ const rendered = await server.respond(new Request('http://sveltekit-prerender/[fallback]'), {
+ prerender: {
+ fallback: true,
+ default: false,
+ dependencies: new Map()
+ }
+ });
- const file = join(out, fallback);
- mkdirp(dirname(file));
- writeFileSync(file, await rendered.text());
- }
+ const file = `${config.kit.outDir}/output/prerendered/fallback.html`;
+ mkdirp(dirname(file));
+ writeFileSync(file, await rendered.text());
return prerendered;
}
diff --git a/packages/kit/src/core/adapt/prerender/queue.js b/packages/kit/src/core/build/prerender/queue.js
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/queue.js
rename to packages/kit/src/core/build/prerender/queue.js
diff --git a/packages/kit/src/core/adapt/prerender/queue.spec.js b/packages/kit/src/core/build/prerender/queue.spec.js
similarity index 100%
rename from packages/kit/src/core/adapt/prerender/queue.spec.js
rename to packages/kit/src/core/build/prerender/queue.spec.js
diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js
index b2c0f71a8918..222251f01281 100644
--- a/packages/kit/src/core/config/index.spec.js
+++ b/packages/kit/src/core/config/index.spec.js
@@ -87,6 +87,7 @@ const get_defaults = (prefix = '') => ({
concurrency: 1,
crawl: true,
createIndexFiles: undefined,
+ default: false,
enabled: true,
entries: ['*'],
force: undefined,
diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js
index b6047884a2d5..bd58e9e2fdee 100644
--- a/packages/kit/src/core/config/options.js
+++ b/packages/kit/src/core/config/options.js
@@ -192,6 +192,7 @@ const options = object(
(keypath) =>
`${keypath} has been removed — it is now controlled by the trailingSlash option. See https://kit.svelte.dev/docs/configuration#trailingslash`
),
+ default: boolean(false),
enabled: boolean(true),
entries: validate(['*'], (input, keypath) => {
if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
diff --git a/packages/kit/src/core/generate_manifest/index.js b/packages/kit/src/core/generate_manifest/index.js
index 00c03e029926..10536af3eb16 100644
--- a/packages/kit/src/core/generate_manifest/index.js
+++ b/packages/kit/src/core/generate_manifest/index.js
@@ -2,17 +2,14 @@ import { s } from '../../utils/misc.js';
import { get_mime_lookup } from '../utils.js';
/**
- * @param {import('types').BuildData} build_data;
- * @param {string} relative_path;
- * @param {import('types').RouteData[]} routes;
- * @param {'esm' | 'cjs'} format
+ * @param {{
+ * build_data: import('types').BuildData;
+ * relative_path: string;
+ * routes: import('types').RouteData[];
+ * format?: 'esm' | 'cjs'
+ * }} opts
*/
-export function generate_manifest(
- build_data,
- relative_path,
- routes = build_data.manifest_data.routes,
- format = 'esm'
-) {
+export function generate_manifest({ build_data, relative_path, routes, format = 'esm' }) {
/** @typedef {{ index: number, path: string }} LookupEntry */
/** @type {Map} */
const bundled_nodes = new Map();
diff --git a/packages/kit/src/core/preview/index.js b/packages/kit/src/core/preview/index.js
index 59c5d1329f09..2295f5a71ada 100644
--- a/packages/kit/src/core/preview/index.js
+++ b/packages/kit/src/core/preview/index.js
@@ -7,13 +7,23 @@ import { pathToFileURL } from 'url';
import { getRequest, setResponse } from '../../node.js';
import { installFetch } from '../../install-fetch.js';
import { SVELTE_KIT_ASSETS } from '../constants.js';
+import { normalize_path } from '../../utils/url.js';
-/** @param {string} dir */
+/** @typedef {import('http').IncomingMessage} Req */
+/** @typedef {import('http').ServerResponse} Res */
+/** @typedef {(req: Req, res: Res, next: () => void) => void} Handler */
+
+/**
+ * @param {string} dir
+ * @returns {Handler}
+ */
const mutable = (dir) =>
- sirv(dir, {
- etag: true,
- maxAge: 0
- });
+ fs.existsSync(dir)
+ ? sirv(dir, {
+ etag: true,
+ maxAge: 0
+ })
+ : (req, res, next) => next();
/**
* @param {{
@@ -27,96 +37,124 @@ const mutable = (dir) =>
export async function preview({ port, host, config, https: use_https = false }) {
installFetch();
+ const { paths } = config.kit;
+ const base = paths.base;
+ const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
+
+ const etag = `"${Date.now()}"`;
+
const index_file = join(config.kit.outDir, 'output/server/index.js');
const manifest_file = join(config.kit.outDir, 'output/server/manifest.js');
/** @type {import('types').ServerModule} */
const { Server, override } = await import(pathToFileURL(index_file).href);
-
const { manifest } = await import(pathToFileURL(manifest_file).href);
- /** @type {import('sirv').RequestHandler} */
- const static_handler = fs.existsSync(config.kit.files.assets)
- ? mutable(config.kit.files.assets)
- : (_req, _res, next) => {
- if (!next) throw new Error('No next() handler is available');
- return next();
- };
-
- const assets_handler = sirv(join(config.kit.outDir, 'output/client'), {
- maxAge: 31536000,
- immutable: true
- });
-
- const has_asset_path = !!config.kit.paths.assets;
+ const server = new Server(manifest);
override({
- paths: {
- base: config.kit.paths.base,
- assets: has_asset_path ? SVELTE_KIT_ASSETS : config.kit.paths.base
- },
+ paths: { base, assets },
prerendering: false,
protocol: use_https ? 'https' : 'http',
read: (file) => fs.readFileSync(join(config.kit.files.assets, file))
});
- const server = new Server(manifest);
-
- /** @type {import('vite').UserConfig} */
- const vite_config = (config.kit.vite && (await config.kit.vite())) || {};
+ const handle = compose([
+ // files in `static`
+ scoped(assets, mutable(config.kit.files.assets)),
+
+ // immutable generated client assets
+ scoped(
+ assets,
+ sirv(join(config.kit.outDir, 'output/client'), {
+ maxAge: 31536000,
+ immutable: true
+ })
+ ),
+
+ // prerendered dependencies
+ scoped(base, mutable(join(config.kit.outDir, 'output/prerendered/dependencies'))),
+
+ // prerendered pages (we can't just use sirv because we need to
+ // preserve the correct trailingSlash behaviour)
+ scoped(base, (req, res, next) => {
+ let if_none_match_value = req.headers['if-none-match'];
+
+ if (if_none_match_value?.startsWith('W/"')) {
+ if_none_match_value = if_none_match_value.substring(2);
+ }
- const http_server = await get_server(use_https, vite_config, (req, res) => {
- if (req.url == null) {
- throw new Error('Invalid request url');
- }
+ if (if_none_match_value === etag) {
+ res.statusCode = 304;
+ res.end();
+ return;
+ }
- const initial_url = req.url;
+ const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy');
- const render_handler = async () => {
- if (initial_url.startsWith(config.kit.paths.base)) {
- const protocol = use_https ? 'https' : 'http';
- const host = req.headers['host'];
+ const normalized = normalize_path(pathname, config.kit.trailingSlash);
- let request;
+ if (normalized !== pathname) {
+ res.writeHead(307, {
+ location: normalized + search
+ });
+ res.end();
+ }
- try {
- req.url = initial_url;
- request = await getRequest(`${protocol}://${host}`, req);
- } catch (/** @type {any} */ err) {
- res.statusCode = err.status || 400;
- return res.end(err.reason || 'Invalid request body');
+ // only treat this as a page if it doesn't include an extension
+ if (pathname === '/' || /\/[^./]+\/?$/.test(pathname)) {
+ const file = join(
+ config.kit.outDir,
+ 'output/prerendered/pages' + pathname + (pathname.endsWith('/') ? 'index.html' : '.html')
+ );
+
+ if (fs.existsSync(file)) {
+ res.writeHead(200, {
+ 'content-type': 'text/html',
+ etag
+ });
+
+ fs.createReadStream(file).pipe(res);
+ return;
}
-
- setResponse(res, await server.respond(request));
} else {
- res.statusCode = 404;
- res.end('Not found');
+ next();
}
- };
-
- if (has_asset_path) {
- if (initial_url.startsWith(SVELTE_KIT_ASSETS)) {
- // custom assets path
- req.url = initial_url.slice(SVELTE_KIT_ASSETS.length);
- assets_handler(req, res, () => {
- static_handler(req, res, render_handler);
- });
- } else {
- render_handler();
- }
- } else {
- if (initial_url.startsWith(config.kit.paths.base)) {
- req.url = initial_url.slice(config.kit.paths.base.length);
+ }),
+
+ // SSR
+ scoped(base, async (req, res) => {
+ const protocol = use_https ? 'https' : 'http';
+ const host = req.headers['host'];
+
+ let request;
+
+ try {
+ request = await getRequest(`${protocol}://${host}`, req);
+ } catch (/** @type {any} */ err) {
+ res.statusCode = err.status || 400;
+ return res.end(err.reason || 'Invalid request body');
}
- assets_handler(req, res, () => {
- static_handler(req, res, render_handler);
- });
+
+ setResponse(res, await server.respond(request));
+ })
+ ]);
+
+ const vite_config = (config.kit.vite && (await config.kit.vite())) || {};
+
+ const http_server = await get_server(use_https, vite_config, (req, res) => {
+ if (req.url == null) {
+ throw new Error('Invalid request url');
}
- });
- await http_server.listen(port, host || '0.0.0.0');
+ handle(req, res);
+ });
- return Promise.resolve(http_server);
+ return new Promise((fulfil) => {
+ http_server.listen(port, host || '0.0.0.0', () => {
+ fulfil(http_server);
+ });
+ });
}
/**
@@ -142,9 +180,51 @@ async function get_server(use_https, user_config, handler) {
}
}
- return Promise.resolve(
- use_https
- ? https.createServer(/** @type {https.ServerOptions} */ (https_options), handler)
- : http.createServer(handler)
- );
+ return use_https
+ ? https.createServer(/** @type {https.ServerOptions} */ (https_options), handler)
+ : http.createServer(handler);
+}
+
+/** @param {Handler[]} handlers */
+function compose(handlers) {
+ /**
+ * @param {Req} req
+ * @param {Res} res
+ */
+ return (req, res) => {
+ /** @param {number} i */
+ function next(i) {
+ const handler = handlers[i];
+
+ if (handler) {
+ handler(req, res, () => next(i + 1));
+ } else {
+ res.statusCode = 404;
+ res.end('Not found');
+ }
+ }
+
+ next(0);
+ };
+}
+
+/**
+ * @param {string} scope
+ * @param {Handler} handler
+ * @returns {Handler}
+ */
+function scoped(scope, handler) {
+ if (scope === '') return handler;
+
+ return (req, res, next) => {
+ if (req.url?.startsWith(scope)) {
+ req.url = req.url.slice(scope.length);
+ handler(req, res, () => {
+ req.url = scope + req.url;
+ next();
+ });
+ } else {
+ next();
+ }
+ };
}
diff --git a/packages/kit/src/runtime/server/page/respond.js b/packages/kit/src/runtime/server/page/respond.js
index 3f610540a871..1d5c45475314 100644
--- a/packages/kit/src/runtime/server/page/respond.js
+++ b/packages/kit/src/runtime/server/page/respond.js
@@ -67,12 +67,16 @@ export async function respond(opts) {
let page_config = get_page_config(leaf, options);
- if (!leaf.prerender && state.prerender && !state.prerender.all) {
- // if the page has `export const prerender = true`, continue,
- // otherwise bail out at this point
- return new Response(undefined, {
- status: 204
- });
+ if (state.prerender) {
+ // if the page isn't marked as prerenderable (or is explicitly
+ // marked NOT prerenderable, if `prerender.default` is `true`),
+ // then bail out at this point
+ const should_prerender = leaf.prerender ?? state.prerender.default;
+ if (!should_prerender) {
+ return new Response(undefined, {
+ status: 204
+ });
+ }
}
/** @type {Array} */
diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js
index 857b5c6b7bd6..40df6e81dd84 100644
--- a/packages/kit/test/apps/basics/svelte.config.js
+++ b/packages/kit/test/apps/basics/svelte.config.js
@@ -3,6 +3,9 @@ import path from 'path';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
+ prerender: {
+ onError: 'continue'
+ },
vite: {
build: {
minify: false
diff --git a/packages/kit/test/prerendering/basics/svelte.config.js b/packages/kit/test/prerendering/basics/svelte.config.js
index e2a911987802..bad007a33f62 100644
--- a/packages/kit/test/prerendering/basics/svelte.config.js
+++ b/packages/kit/test/prerendering/basics/svelte.config.js
@@ -7,6 +7,7 @@ const config = {
adapter: adapter(),
prerender: {
+ default: true,
onError: 'continue'
},
diff --git a/packages/kit/test/prerendering/options/svelte.config.js b/packages/kit/test/prerendering/options/svelte.config.js
index 558a6c06f4e3..d84e1d47641d 100644
--- a/packages/kit/test/prerendering/options/svelte.config.js
+++ b/packages/kit/test/prerendering/options/svelte.config.js
@@ -17,6 +17,10 @@ const config = {
assets: 'https://cdn.example.com/stuff'
},
+ prerender: {
+ default: true
+ },
+
trailingSlash: 'always',
vite: {
diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts
index ff8f0fd7f464..c71ae90b40db 100644
--- a/packages/kit/types/ambient.d.ts
+++ b/packages/kit/types/ambient.d.ts
@@ -228,6 +228,10 @@ declare module '$service-worker' {
* An array of URL strings representing the files in your static directory, or whatever directory is specified by `config.kit.files.assets`. You can customize which files are included from `static` directory using [`config.kit.serviceWorker.files`](/docs/configuration)
*/
export const files: string[];
+ /**
+ * An array of pathnames corresponding to prerendered pages and endpoints.
+ */
+ export const prerendered: string[];
/**
* The result of calling `Date.now()` at build time. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
*/
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index ca8065de695f..8e210c422c4f 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -69,6 +69,7 @@ export interface Config {
prerender?: {
concurrency?: number;
crawl?: boolean;
+ default?: boolean;
enabled?: boolean;
entries?: string[];
onError?: PrerenderOnErrorValue;
diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts
index 139f0a950328..e0e10a0158ab 100644
--- a/packages/kit/types/internal.d.ts
+++ b/packages/kit/types/internal.d.ts
@@ -14,6 +14,7 @@ import {
HttpMethod,
JSONObject,
MaybePromise,
+ Prerendered,
RequestEvent,
RequestOptions,
ResolveOptions,
@@ -63,8 +64,6 @@ export interface BuildData {
methods: Record;
vite_manifest: import('vite').Manifest;
};
- static: string[];
- entries: string[];
}
export type CSRComponent = any; // TODO
@@ -149,8 +148,8 @@ export interface PrerenderDependency {
}
export interface PrerenderOptions {
- fallback?: string;
- all: boolean;
+ fallback?: boolean;
+ default: boolean;
dependencies: Map;
}
diff --git a/packages/kit/types/private.d.ts b/packages/kit/types/private.d.ts
index 48c0659f0ae0..b4beab62d945 100644
--- a/packages/kit/types/private.d.ts
+++ b/packages/kit/types/private.d.ts
@@ -2,7 +2,7 @@
// but which cannot be imported from `@sveltejs/kit`. Care should
// be taken to avoid breaking changes when editing this file
-import { SSRNodeLoader, SSRRoute } from './internal';
+import { SSRNodeLoader, SSRRoute, ValidatedConfig } from './internal';
export interface AdapterEntry {
/**
@@ -35,8 +35,8 @@ export interface Builder {
rimraf(dir: string): void;
mkdirp(dir: string): void;
- appDir: string;
- trailingSlash: TrailingSlash;
+ config: ValidatedConfig;
+ prerendered: Prerendered;
/**
* Create entry points that map to individual functions
@@ -56,6 +56,16 @@ export interface Builder {
* @returns an array of paths corresponding to the files that have been created by the copy
*/
writeClient(dest: string): string[];
+ /**
+ *
+ * @param dest
+ */
+ writePrerendered(
+ dest: string,
+ opts?: {
+ fallback?: string;
+ }
+ ): string[];
/**
* @param dest the destination folder to which files should be copied
* @returns an array of paths corresponding to the files that have been created by the copy
@@ -81,8 +91,6 @@ export interface Builder {
replace?: Record;
}
): string[];
-
- prerender(options: { all?: boolean; dest: string; fallback?: string }): Promise;
}
// Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts