Repository: sveltejs/kit
Pull request #9327 (2023-03-06 01:17:34)

chore(deps): update pnpm to v7.29.0
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pnpm](https://pnpm.io) ([source](https://togithub.com/pnpm/pnpm)) | [`7.28.0` -> `7.29.0`](https://renovatebot.com/diffs/npm/pnpm/7.28.0/7.29.0) | [![age](https://badges.renovateapi.com/packages/npm/pnpm/7.29.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/pnpm/7.29.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/pnpm/7.29.0/compatibility-slim/7.28.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/pnpm/7.29.0/confidence-slim/7.28.0)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>pnpm/pnpm</summary>

### [`v7.29.0`](https://togithub.com/pnpm/pnpm/releases/tag/v7.29.0)

[Compare Source](https://togithub.com/pnpm/pnpm/compare/v7.28.0...v7.29.0)

#### Minor Changes

-   A new setting is now supported: `dedupe-peer-dependents`.

    When this setting is set to `true`, packages with peer dependencies will be deduplicated after peers resolution.

    For instance, let's say we have a workspace with two projects and both of them have `webpack` in their dependencies. `webpack` has `esbuild` in its optional peer dependencies, and one of the projects has `esbuild` in its dependencies. In this case, pnpm will link two instances of `webpack` to the `node_modules/.pnpm` directory: one with `esbuild` and another one without it:

        node_modules
          .pnpm
            webpack@1.0.0_esbuild@1.0.0
            webpack@1.0.0
        project1
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0/node_modules/webpack
        project2
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
            esbuild

    This makes sense because `webpack` is used in two projects, and one of the projects doesn't have `esbuild`, so the two projects cannot share the same instance of `webpack`. However, this is not what most developers expect, especially since in a hoisted `node_modules`, there would only be one instance of `webpack`. Therefore, you may now use the `dedupe-peer-dependents` setting to deduplicate `webpack` when it has no conflicting peer dependencies (explanation at the end). In this case, if we set `dedupe-peer-dependents` to `true`, both projects will use the same `webpack` instance, which is the one that has `esbuild` resolved:

        node_modules
          .pnpm
            webpack@1.0.0_esbuild@1.0.0
        project1
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
        project2
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
            esbuild

    **What are conflicting peer dependencies?** By conflicting peer dependencies we mean a scenario like the following one:

        node_modules
          .pnpm
            webpack@1.0.0_react@16.0.0_esbuild@1.0.0
            webpack@1.0.0_react@17.0.0
        project1
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0/node_modules/webpack
            react (v17)
        project2
          node_modules
            webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
            esbuild
            react (v16)

    In this case, we cannot dedupe `webpack` as `webpack` has `react` in its peer dependencies and `react` is resolved from two different versions in the context of the two projects.

#### Patch Changes

-   The configuration added by `pnpm setup` should check if the pnpm home directory is already in the PATH before adding to the PATH.

    Before this change, this code was added to the shell:

    ```sh
    export PNPM_HOME="$HOME/Library/pnpm"
    export PATH="$PNPM_HOME:$PATH"
    ```

    Now this will be added:

    ```sh
    export PNPM_HOME="$HOME/Library/pnpm"
    case ":$PATH:" in
      *":$PNPM_HOME:"*) ;;
      *) export PATH="$PNPM_HOME:$PATH" ;;
    esac
    ```

-   Add `skipped` status in exec report summary when script is missing [#&#8203;6139](https://togithub.com/pnpm/pnpm/pull/6139).

-   `pnpm env -g` should fail with a meaningful error message if pnpm cannot find the pnpm home directory, which is the directory into which Node.js is installed.

-   Should not throw an error when local dependency use file protocol [#&#8203;6115](https://togithub.com/pnpm/pnpm/issues/6115).

-   Fix the incorrect error block when subproject has been patched [#&#8203;6183](https://togithub.com/pnpm/pnpm/issues/6183)

#### Our Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/novu.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/novu_light.svg" />
            <img src="https://pnpm.io/img/users/novu.svg" width="180" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
        <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" />
            <img src="https://pnpm.io/img/users/prisma.svg" width="180" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://www.flightcontrol.dev/?ref=pnpm" target="_blank"><img src="https://pnpm.io/img/users/flightcontrol.png" width="240"></a>
      </td>
    </tr>
  </tbody>
</table>

#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80">
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" />
            <img src="https://pnpm.io/img/users/vercel.svg" width="180" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
        <a href="https://doppler.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/doppler.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/doppler_light.svg" />
            <img src="https://pnpm.io/img/users/doppler.svg" width="280" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" />
            <img src="https://pnpm.io/img/users/depot.svg" width="200" />
          </picture>
        </a>
      </td>
    </tr>
  </tbody>
</table>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/sveltejs/kit).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNTQuNyIsInVwZGF0ZWRJblZlciI6IjM0LjE1NC43In0=-->



Patch:
diff --git a/.changeset/nasty-elephants-grab.md b/.changeset/nasty-elephants-grab.md
new file mode 100644
index 000000000..09f489695
--- /dev/null
+++ b/.changeset/nasty-elephants-grab.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: respect `<base>` when crawling
diff --git a/.changeset/silver-teachers-lick.md b/.changeset/silver-teachers-lick.md
new file mode 100644
index 000000000..c267124f7
--- /dev/null
+++ b/.changeset/silver-teachers-lick.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: scroll before resetting focus, to avoid flash of unscrolled content
diff --git a/.changeset/tasty-spies-listen.md b/.changeset/tasty-spies-listen.md
new file mode 100644
index 000000000..eb05795e8
--- /dev/null
+++ b/.changeset/tasty-spies-listen.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: omit hash from global during development
diff --git a/package.json b/package.json
index 31fa29573..260162c8b 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
 		"tiny-glob": "^0.2.9",
 		"typescript": "^4.9.4"
 	},
-	"packageManager": "pnpm@7.28.0",
+	"packageManager": "pnpm@7.29.0",
 	"engines": {
 		"pnpm": "^7.0.0"
 	},
diff --git a/packages/kit/src/core/postbuild/crawl.js b/packages/kit/src/core/postbuild/crawl.js
index fd1bd4c9e..4132ba6c1 100644
--- a/packages/kit/src/core/postbuild/crawl.js
+++ b/packages/kit/src/core/postbuild/crawl.js
@@ -1,3 +1,4 @@
+import { resolve } from '../../utils/url.js';
 import { decode } from './entities.js';
 
 const DOCTYPE = 'DOCTYPE';
@@ -12,8 +13,11 @@ const ATTRIBUTE_NAME = /[^\t\n\f />"'=]/;
 
 const WHITESPACE = /[\s\n\r]/;
 
-/** @param {string} html */
-export function crawl(html) {
+/**
+ * @param {string} html
+ * @param {string} base
+ */
+export function crawl(html, base) {
 	/** @type {string[]} */
 	const ids = [];
 
@@ -157,7 +161,11 @@ export function crawl(html) {
 							value = decode(value);
 
 							if (name === 'href') {
-								href = value;
+								if (tag === 'BASE') {
+									base = resolve(base, value);
+								} else {
+									href = resolve(base, value);
+								}
 							} else if (name === 'id') {
 								ids.push(value);
 							} else if (name === 'name') {
@@ -165,7 +173,7 @@ export function crawl(html) {
 							} else if (name === 'rel') {
 								rel = value;
 							} else if (name === 'src') {
-								if (value) hrefs.push(value);
+								if (value) hrefs.push(resolve(base, value));
 							} else if (name === 'srcset') {
 								const candidates = [];
 								let insideURL = true;
@@ -183,7 +191,7 @@ export function crawl(html) {
 								candidates.push(value);
 								for (const candidate of candidates) {
 									const src = candidate.split(WHITESPACE)[0];
-									if (src) hrefs.push(src);
+									if (src) hrefs.push(resolve(base, src));
 								}
 							}
 						} else {
@@ -195,7 +203,7 @@ export function crawl(html) {
 				}
 
 				if (href && !/\bexternal\b/i.test(rel)) {
-					hrefs.push(href);
+					hrefs.push(resolve(base, href));
 				}
 			}
 		}
diff --git a/packages/kit/src/core/postbuild/crawl.spec.js b/packages/kit/src/core/postbuild/crawl.spec.js
index bad1a21e7..c62b15552 100644
--- a/packages/kit/src/core/postbuild/crawl.spec.js
+++ b/packages/kit/src/core/postbuild/crawl.spec.js
@@ -13,7 +13,7 @@ for (const fixture of fs.readdirSync(fixtures)) {
 
 		// const start = Date.now();
 
-		const output = crawl(input);
+		const output = crawl(input, '/');
 
 		// uncomment to see how long it took
 		// console.error(fixture, Date.now() - start);
diff --git a/packages/kit/src/core/postbuild/fixtures/base/input.html b/packages/kit/src/core/postbuild/fixtures/base/input.html
new file mode 100644
index 000000000..82a5aa945
--- /dev/null
+++ b/packages/kit/src/core/postbuild/fixtures/base/input.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<base href="/base-path/" />
+		<link rel="stylesheet" href="styles.css" />
+		<link rel="icon" href="favicon.png" />
+	</head>
+	<body>
+		<a href="https://external.com">https://external.com</a>
+		<a href="wheee">/wheee</a>
+		<a data-sveltekit-prefetch href="wheee2">/wheee</a>
+		<a href="wheee3" data-sveltekit-prefetch>/wheee</a>
+		<a href="wheee4">/wheee</a>
+	</body>
+</html>
diff --git a/packages/kit/src/core/postbuild/fixtures/base/output.json b/packages/kit/src/core/postbuild/fixtures/base/output.json
new file mode 100644
index 000000000..af7a9e70a
--- /dev/null
+++ b/packages/kit/src/core/postbuild/fixtures/base/output.json
@@ -0,0 +1,12 @@
+{
+	"hrefs": [
+		"/base-path/styles.css",
+		"/base-path/favicon.png",
+		"https://external.com",
+		"/base-path/wheee",
+		"/base-path/wheee2",
+		"/base-path/wheee3",
+		"/base-path/wheee4"
+	],
+	"ids": []
+}
diff --git a/packages/kit/src/core/postbuild/fixtures/basic-srcset/output.json b/packages/kit/src/core/postbuild/fixtures/basic-srcset/output.json
index cf0e24ae4..536c3d3f3 100644
--- a/packages/kit/src/core/postbuild/fixtures/basic-srcset/output.json
+++ b/packages/kit/src/core/postbuild/fixtures/basic-srcset/output.json
@@ -1,11 +1,11 @@
 {
 	"hrefs": [
-		"header.png",
+		"/header.png",
 		"https://example.com/w_200,q_100/header.png",
-		"header640.png",
-		"header960.png",
-		"header1024.png",
-		"header.png"
+		"/header640.png",
+		"/header960.png",
+		"/header1024.png",
+		"/header.png"
 	],
 	"ids": []
 }
diff --git a/packages/kit/src/core/postbuild/fixtures/ids/output.json b/packages/kit/src/core/postbuild/fixtures/ids/output.json
index 1ad4d8f3f..e749d3128 100644
--- a/packages/kit/src/core/postbuild/fixtures/ids/output.json
+++ b/packages/kit/src/core/postbuild/fixtures/ids/output.json
@@ -1,4 +1,4 @@
 {
-	"hrefs": ["#encöded"],
+	"hrefs": ["/#encöded"],
 	"ids": ["before", "after", "encöded"]
 }
diff --git a/packages/kit/src/core/postbuild/prerender.js b/packages/kit/src/core/postbuild/prerender.js
index cdfaacb0d..bd938baf8 100644
--- a/packages/kit/src/core/postbuild/prerender.js
+++ b/packages/kit/src/core/postbuild/prerender.js
@@ -240,17 +240,14 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) {
 		const headers = Object.fromEntries(response.headers);
 
 		if (config.prerender.crawl && headers['content-type'] === 'text/html') {
-			const { ids, hrefs } = crawl(body.toString());
+			const { ids, hrefs } = crawl(body.toString(), decoded);
 
 			actual_hashlinks.set(decoded, ids);
 
 			for (const href of hrefs) {
-				if (href.startsWith('data:')) continue;
+				if (!is_root_relative(href)) continue;
 
-				const resolved = resolve(encoded, href);
-				if (!is_root_relative(resolved)) continue;
-
-				const { pathname, search, hash } = new URL(resolved, 'http://localhost');
+				const { pathname, search, hash } = new URL(href, 'http://localhost');
 
 				if (search) {
 					// TODO warn that query strings have no effect on statically-exported pages
diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js
index 569064bb9..028d873e3 100644
--- a/packages/kit/src/exports/vite/index.js
+++ b/packages/kit/src/exports/vite/index.js
@@ -335,7 +335,10 @@ function kit({ svelte_config }) {
 
 		async load(id, options) {
 			const browser = !options?.ssr;
-			const global = `globalThis.__sveltekit_${version_hash}`;
+
+			const global = is_build
+				? `globalThis.__sveltekit_${version_hash}`
+				: `globalThis.__sveltekit_dev`;
 
 			if (options?.ssr === false && process.env.TEST !== 'true') {
 				const normalized_cwd = vite.normalizePath(cwd);
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 11f83e40b..f4c12fe23 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -379,17 +379,7 @@ export function create_client(app, target) {
 			// need to render the DOM before we can scroll to the rendered elements and do focus management
 			await tick();
 
-			const changed_focus =
-				// reset focus only if any manual focus management didn't override it
-				document.activeElement !== activeElement &&
-				// also refocus when activeElement is body already because the
-				// focus event might not have been fired on it yet
-				document.activeElement !== document.body;
-
-			if (!keepfocus && !changed_focus) {
-				await reset_focus();
-			}
-
+			// we reset scroll before dealing with focus, to avoid a flash of unscrolled content
 			if (autoscroll) {
 				const deep_linked =
 					url.hash && document.getElementById(decodeURIComponent(url.hash.slice(1)));
@@ -404,6 +394,17 @@ export function create_client(app, target) {
 					scrollTo(0, 0);
 				}
 			}
+
+			const changed_focus =
+				// reset focus only if any manual focus management didn't override it
+				document.activeElement !== activeElement &&
+				// also refocus when activeElement is body already because the
+				// focus event might not have been fired on it yet
+				document.activeElement !== document.body;
+
+			if (!keepfocus && !changed_focus) {
+				await reset_focus();
+			}
 		} else {
 			await tick();
 		}
diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js
index da2659fc4..22be19737 100644
--- a/packages/kit/src/runtime/server/page/render.js
+++ b/packages/kit/src/runtime/server/page/render.js
@@ -268,7 +268,7 @@ export async function render_response({
 		}
 	}
 
-	const global = `__sveltekit_${options.version_hash}`;
+	const global = __SVELTEKIT_DEV__ ? `__sveltekit_dev` : `__sveltekit_${options.version_hash}`;
 
 	const { data, chunks } = get_data(
 		event,
diff --git a/packages/kit/src/utils/url.spec.js b/packages/kit/src/utils/url.spec.js
index 383c30ea2..906a48046 100644
--- a/packages/kit/src/utils/url.spec.js
+++ b/packages/kit/src/utils/url.spec.js
@@ -54,6 +54,10 @@ describe('resolve', (test) => {
 	test('resolves a fragment link', () => {
 		assert.equal(resolve('/a/b/c', '#foo'), '/a/b/c#foo');
 	});
+
+	test('resolves data: urls', () => {
+		assert.equal(resolve('/a/b/c', 'data:text/plain,hello'), 'data:text/plain,hello');
+	});
 });
 
 describe('normalize_path', (test) => {
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index 58027c9c8..a5a0d2637 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -458,6 +458,8 @@ export interface KitConfig {
 		 *
 		 * 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 `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 `<base>` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `<base>` URL rather than the current page.
 		 * @default undefined
 		 */
 		relative?: boolean | undefined;
@@ -572,7 +574,22 @@ export interface KitConfig {
 	 */
 	version?: {
 		/**
-		 * The current app version string. If specified, this must be deterministic (e.g. a commit ref rather than `Math.random()` or `Date.now().toString()`), otherwise defaults to a timestamp of the build
+		 * The current app version string. If specified, this must be deterministic (e.g. a commit ref rather than `Math.random()` or `Date.now().toString()`), otherwise defaults to a timestamp of the build.
+		 *
+		 * For example, to use the current commit hash, you could do use `git rev-parse HEAD`:
+		 *
+		 * ```js
+		 * /// file: svelte.config.js
+		 * import * as child_process from 'node:child_process';
+		 *
+		 * export default {
+		 *   kit: {
+		 *     version: {
+		 *       name: child_process.execSync('git rev-parse HEAD').toString().trim()
+		 *     }
+		 *   }
+		 * };
+		 * ```
 		 */
 		name?: string;
 		/**
diff --git a/sites/kit.svelte.dev/src/lib/docs/server/index.js b/sites/kit.svelte.dev/src/lib/docs/server/index.js
index 604de5301..772321557 100644
--- a/sites/kit.svelte.dev/src/lib/docs/server/index.js
+++ b/sites/kit.svelte.dev/src/lib/docs/server/index.js
@@ -8,7 +8,7 @@ import 'prismjs/components/prism-typescript.js';
 import 'prism-svelte';
 import { escape, extract_frontmatter, transform } from './markdown.js';
 import { modules } from './type-info.js';
-import { render, replace_placeholders } from './render.js';
+import { replace_placeholders } from './render.js';
 import { parse_route_id } from '../../../../../../packages/kit/src/utils/routing.js';
 import ts from 'typescript';
 import MagicString from 'magic-string';
@@ -164,6 +164,10 @@ export async function read_file(file) {
 						injected.push('// @errors: 7006 7031');
 					}
 
+					if (file.endsWith('10-configuration.md')) {
+						injected.push('// @errors: 2307');
+					}
+
 					// another special case
 					if (source.includes('$lib/types')) {
 						injected.push(`declare module '$lib/types' { export interface User {} }`);
@@ -580,9 +584,11 @@ function convert_to_ts(js_code, indent = '', offset = '') {
 				imports.set(from, new Set([name]));
 			}
 			if (generics !== undefined) {
-				return [name, generics
-					.replaceAll("*", "") // get rid of JSDoc asterisks
-					.replace("  }>", "}>") // unindent closing brace
+				return [
+					name,
+					generics
+						.replaceAll('*', '') // get rid of JSDoc asterisks
+						.replace('  }>', '}>') // unindent closing brace
 				];
 			}
 		}
diff --git a/sites/kit.svelte.dev/src/lib/docs/server/render.js b/sites/kit.svelte.dev/src/lib/docs/server/render.js
index e295909e2..6762c17ce 100644
--- a/sites/kit.svelte.dev/src/lib/docs/server/render.js
+++ b/sites/kit.svelte.dev/src/lib/docs/server/render.js
@@ -95,29 +95,6 @@ export function replace_placeholders(content) {
 		});
 }
 
-/** @param {'types' | 'exports'} kind */
-export function render(kind) {
-	return modules
-		.map((module) => {
-			// special case — we want to include $lib etc in the modules page
-			const is_exempt = kind === 'exports' && module.exempt;
-			const skip = module[kind].length === 0 && !is_exempt;
-
-			if (skip) return '';
-
-			return `## ${module.name}\n\n${module.comment}\n\n${module[kind]
-				.map((type) => {
-					const markdown =
-						`<div class="ts-block">${fence(type.snippet)}` +
-						type.children.map(stringify).join('\n\n') +
-						`</div>`;
-					return `### ${type.name}\n\n${type.comment}\n\n${markdown}`;
-				})
-				.join('\n\n')}`;
-		})
-		.join('\n\n');
-}
-
 /**
  * @param {string} code
  * @param {string} lang


Test patch:
diff --git a/packages/kit/test/prerendering/paths-base/src/app.html b/packages/kit/test/prerendering/paths-base/src/app.html
index cee411bbe..19fc5c4ab 100644
--- a/packages/kit/test/prerendering/paths-base/src/app.html
+++ b/packages/kit/test/prerendering/paths-base/src/app.html
@@ -3,7 +3,8 @@
 	<head>
 		<meta charset="utf-8" />
 		<meta name="viewport" content="width=device-width" />
-		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
+		<base href="/path-base/" />
+		<link rel="icon" href="favicon.png" />
 		%sveltekit.head%
 	</head>
 	<body>
diff --git a/packages/kit/test/prerendering/paths-base/src/routes/+page.svelte b/packages/kit/test/prerendering/paths-base/src/routes/+page.svelte
index 0e0a3e0d6..715969239 100644
--- a/packages/kit/test/prerendering/paths-base/src/routes/+page.svelte
+++ b/packages/kit/test/prerendering/paths-base/src/routes/+page.svelte
@@ -1,8 +1,4 @@
-<script>
-	import { base } from '$app/paths'
-</script>
-
 <div>
 	<h1>Main Page</h1>
-	<a href="{base}/nested">Nested Link</a>
+	<a href="nested">Nested Link</a>
 </div>
diff --git a/packages/kit/test/prerendering/paths-base/src/routes/a/b/c/+page.svelte b/packages/kit/test/prerendering/paths-base/src/routes/a/b/c/+page.svelte
new file mode 100644
index 000000000..e2608ff10
--- /dev/null
+++ b/packages/kit/test/prerendering/paths-base/src/routes/a/b/c/+page.svelte
@@ -0,0 +1,1 @@
+<a href="a/b/d">a/b/d</a>
diff --git a/packages/kit/test/prerendering/paths-base/src/routes/a/b/d/+page.svelte b/packages/kit/test/prerendering/paths-base/src/routes/a/b/d/+page.svelte
new file mode 100644
index 000000000..46a8aaeaf
--- /dev/null
+++ b/packages/kit/test/prerendering/paths-base/src/routes/a/b/d/+page.svelte
@@ -0,0 +1,1 @@
+<a href="a/b/c">a/b/c</a>
diff --git a/packages/kit/test/prerendering/paths-base/svelte.config.js b/packages/kit/test/prerendering/paths-base/svelte.config.js
index 083606280..27e3e4661 100644
--- a/packages/kit/test/prerendering/paths-base/svelte.config.js
+++ b/packages/kit/test/prerendering/paths-base/svelte.config.js
@@ -6,7 +6,8 @@ const config = {
 		adapter: adapter(),
 
 		paths: {
-			base: '/path-base'
+			base: '/path-base',
+			relative: false
 		}
 	}
 };
diff --git a/packages/kit/test/prerendering/paths-base/test/test.js b/packages/kit/test/prerendering/paths-base/test/test.js
index 92c8dba2d..b12f6ee9a 100644
--- a/packages/kit/test/prerendering/paths-base/test/test.js
+++ b/packages/kit/test/prerendering/paths-base/test/test.js
@@ -10,7 +10,7 @@ const read = (file) => fs.readFileSync(`${build}/${file}`, 'utf-8');
 
 test('prerenders /path-base', () => {
 	const content = read('index.html');
-	assert.ok(content.includes('/path-base/favicon.png') && content.includes('/path-base/nested'));
+	assert.ok(content.includes('favicon.png') && content.includes('nested'));
 });
 
 test('prerenders /path-base/redirect', () => {