diff --git a/.changeset/tall-suns-protect.md b/.changeset/tall-suns-protect.md
new file mode 100644
index 000000000000..21f8fa055fa0
--- /dev/null
+++ b/.changeset/tall-suns-protect.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': major
+---
+
+breaking: undefined is no longer a valid value for paths.relative
diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js
index faaf138aebb3..e0e29a009ae5 100644
--- a/packages/kit/src/core/config/index.spec.js
+++ b/packages/kit/src/core/config/index.spec.js
@@ -102,7 +102,7 @@ const get_defaults = (prefix = '') => ({
paths: {
base: '',
assets: '',
- relative: undefined
+ relative: true
},
prerender: {
concurrency: 1,
@@ -321,7 +321,7 @@ validate_paths(
{
base: '/path/to/base',
assets: '',
- relative: undefined
+ relative: true
}
);
@@ -333,7 +333,7 @@ validate_paths(
{
base: '',
assets: 'https://cdn.example.com',
- relative: undefined
+ relative: true
}
);
@@ -346,7 +346,7 @@ validate_paths(
{
base: '/path/to/base',
assets: 'https://cdn.example.com',
- relative: undefined
+ relative: true
}
);
diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js
index 2d0c928d9290..67f593e2d590 100644
--- a/packages/kit/src/core/config/options.js
+++ b/packages/kit/src/core/config/options.js
@@ -179,13 +179,7 @@ const options = object(
return input;
}),
- relative: validate(undefined, (input, keypath) => {
- if (typeof input !== 'boolean') {
- throw new Error(`${keypath} option must be a boolean or undefined`);
- }
-
- return input;
- })
+ relative: boolean(true)
}),
prerender: object({
diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts
index 4e5e4bce53aa..37f394588435 100644
--- a/packages/kit/src/exports/public.d.ts
+++ b/packages/kit/src/exports/public.d.ts
@@ -473,15 +473,18 @@ export interface KitConfig {
*/
base?: '' | `/${string}`;
/**
- * Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config.
+ * Whether to use relative asset paths.
*
- * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML.
+ * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML.
* If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL
*
* If your app uses a `` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `` URL rather than the current page.
- * @default undefined
+ *
+ * In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config.
+ *
+ * @default true
*/
- relative?: boolean | undefined;
+ relative?: boolean;
};
/**
* See [Prerendering](https://kit.svelte.dev/docs/page-options#prerender).
diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js
index dbc558151fd2..0edbeb333dab 100644
--- a/packages/kit/src/runtime/server/page/render.js
+++ b/packages/kit/src/runtime/server/page/render.js
@@ -95,7 +95,7 @@ export async function render_response({
let base_expression = s(paths.base);
// if appropriate, use relative paths for greater portability
- if (paths.relative !== false && !state.prerendering?.fallback) {
+ if (paths.relative && !state.prerendering?.fallback) {
const segments = event.url.pathname.slice(paths.base.length).split('/').slice(2);
base = segments.map(() => '..').join('/') || '.';
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js
index d4b56ba50c92..b64daa01ea31 100644
--- a/packages/kit/test/apps/basics/test/test.js
+++ b/packages/kit/test/apps/basics/test/test.js
@@ -642,24 +642,16 @@ test.describe('$app/environment', () => {
});
test.describe('$app/paths', () => {
- test('includes paths', async ({ page }) => {
+ test('includes paths', async ({ page, javaScriptEnabled }) => {
await page.goto('/paths');
- expect(await page.innerHTML('pre')).toBe(
- JSON.stringify({
- base: '',
- assets: ''
- })
- );
+ let base = javaScriptEnabled ? '' : '.';
+ expect(await page.innerHTML('pre')).toBe(JSON.stringify({ base, assets: base }));
await page.goto('/paths/deeply/nested');
- expect(await page.innerHTML('pre')).toBe(
- JSON.stringify({
- base: '',
- assets: ''
- })
- );
+ base = javaScriptEnabled ? '' : '../..';
+ expect(await page.innerHTML('pre')).toBe(JSON.stringify({ base, assets: base }));
});
// some browsers will re-request assets after a `pushState`