Repository: sveltejs/kit
Pull request #8678 (2023-01-23 16:45:35)

chore: make site work when base path is configured
We've got a number of base path issues I've been looking at. It's helpful to be able to run the site with a base path so that I have something to debug against. I don't expect that we'll necessarily maintain kit.svelte.dev in a perfectly working state with base path, but it's helpful to have something nonetheless

I found one serious bug while working on this and fixed it in another PR (https://github.com/sveltejs/kit/pull/8683)

This also bumps `vite-imagetools` which just fixed base path support in its latest release, so it was a good test of that as well

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: 60e696ffc88d3adfe0895fb558eef7757af7a280

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/sveltejs/kit/new/site?filename=.changeset/lovely-rules-tie.md&value=---%0A%0A---%0A%0Achore%3A%20make%20site%20work%20when%20base%20path%20is%20configured%0A)



Patch:
diff --git a/.changeset/cold-students-repair.md b/.changeset/cold-students-repair.md
new file mode 100644
index 000000000..e42bd95c6
--- /dev/null
+++ b/.changeset/cold-students-repair.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: allow importing assets while using base path
diff --git a/.changeset/eight-points-fly.md b/.changeset/eight-points-fly.md
deleted file mode 100644
index b4fb40544..000000000
--- a/.changeset/eight-points-fly.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@sveltejs/kit": patch
----
-
-chore: update undici to v5.16.0
diff --git a/.changeset/two-pens-exist.md b/.changeset/two-pens-exist.md
deleted file mode 100644
index dbcdc7629..000000000
--- a/.changeset/two-pens-exist.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@sveltejs/adapter-netlify': patch
----
-
-chore: update link to docs for missing netlify.toml warning
diff --git a/documentation/docs/10-getting-started/10-introduction.md b/documentation/docs/10-getting-started/10-introduction.md
index 555c21f17..b9f0eea1a 100644
--- a/documentation/docs/10-getting-started/10-introduction.md
+++ b/documentation/docs/10-getting-started/10-introduction.md
@@ -20,6 +20,6 @@ In short, Svelte is a way of writing user interface components — like a naviga
 
 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.
 
-SvelteKit provides basic functionality like a [router](/docs/glossary#routing) — which updates the UI when a link is clicked — and [server-side rendering (SSR)](/docs/glossary#ssr). But beyond that, building an app with all the modern best practices is fiendishly complicated. Those practices include [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations), so that you load only the minimal required code; [offline support](/docs/service-workers); [preloading](/docs/link-options#data-sveltekit-preload-data) pages before the user initiates navigation; [configurable rendering](/docs/page-options) that allows you to render different parts of your app on the server with [SSR](/docs/glossary#ssr), in the browser [client-side rendering](/docs/glossary#csr), or at build-time with [prerendering](/docs/glossary#prerendering); and many other things. SvelteKit does all the boring stuff for you so that you can get on with the creative part.
+SvelteKit provides basic functionality like a [router](glossary#routing) — which updates the UI when a link is clicked — and [server-side rendering (SSR)](glossary#ssr). But beyond that, building an app with all the modern best practices is fiendishly complicated. Those practices include [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations), so that you load only the minimal required code; [offline support](service-workers); [preloading](link-options#data-sveltekit-preload-data) pages before the user initiates navigation; [configurable rendering](page-options) that allows you to render different parts of your app on the server with [SSR](glossary#ssr), in the browser [client-side rendering](glossary#csr), or at build-time with [prerendering](glossary#prerendering); and many other things. SvelteKit does all the boring stuff for you so that you can get on with the creative part.
 
 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).
diff --git a/documentation/docs/10-getting-started/30-project-structure.md b/documentation/docs/10-getting-started/30-project-structure.md
index c75a46eb4..91ae38473 100644
--- a/documentation/docs/10-getting-started/30-project-structure.md
+++ b/documentation/docs/10-getting-started/30-project-structure.md
@@ -36,21 +36,21 @@ You'll also find common files like `.gitignore` and `.npmrc` (and `.prettierrc`
 
 The `src` directory contains the meat of your project.
 
-- `lib` contains your library code (utilities and components), which can be imported via the [`$lib`](/docs/modules#$lib) alias, or packaged up for distribution using [`svelte-package`](/docs/packaging)
-  - `server` contains your server-only library code. It can be imported by using the [`$lib/server`](/docs/server-only-modules) alias. SvelteKit will prevent you from importing these in client code.
-- `params` contains any [param matchers](/docs/advanced-routing#matching) your app needs
-- `routes` contains the [routes](/docs/routing) of your application. You can also colocate other components that are only used within a single route here
+- `lib` contains your library code (utilities and components), which can be imported via the [`$lib`](modules#$lib) alias, or packaged up for distribution using [`svelte-package`](packaging)
+  - `server` contains your server-only library code. It can be imported by using the [`$lib/server`](server-only-modules) alias. SvelteKit will prevent you from importing these in client code.
+- `params` contains any [param matchers](advanced-routing#matching) your app needs
+- `routes` contains the [routes](routing) of your application. You can also colocate other components that are only used within a single route here
 - `app.html` is your page template — an HTML document containing the following placeholders:
   - `%sveltekit.head%` — `<link>` and `<script>` elements needed by the app, plus any `<svelte:head>` content
   - `%sveltekit.body%` — the markup for a rendered page. This should live inside a `<div>` or other element, rather than directly inside `<body>`, to prevent bugs caused by browser extensions injecting elements that are then destroyed by the hydration process. SvelteKit will warn you in development if this is not the case
-  - `%sveltekit.assets%` — either [`paths.assets`](/docs/configuration#paths), if specified, or a relative path to [`paths.base`](/docs/configuration#paths)
-  - `%sveltekit.nonce%` — a [CSP](/docs/configuration#csp) nonce for manually included links and scripts, if used
+  - `%sveltekit.assets%` — either [`paths.assets`](configuration#paths), if specified, or a relative path to [`paths.base`](configuration#paths)
+  - `%sveltekit.nonce%` — a [CSP](configuration#csp) nonce for manually included links and scripts, if used
   - `%sveltekit.env.[NAME]%` - this will be replaced at render time with the `[NAME]` environment variable, which must begin with the [`publicPrefix`](https://kit.svelte.dev/docs/configuration#env) (usually `PUBLIC_`). It will fallback to `''` if not matched.
 - `error.html` (optional) is the page that is rendered when everything else fails. It can contain the following placeholders:
   - `%sveltekit.status%` — the HTTP status
   - `%sveltekit.error.message%` — the error message
-- `hooks.js` (optional) contains your application's [hooks](/docs/hooks)
-- `service-worker.js` (optional) contains your [service worker](/docs/service-workers)
+- `hooks.js` (optional) contains your application's [hooks](hooks)
+- `service-worker.js` (optional) contains your [service worker](service-workers)
 
 You can use `.ts` files instead of `.js` files, if using TypeScript.
 
@@ -72,7 +72,7 @@ When you create a project with `npm create svelte@latest`, you'll also notice th
 
 ### svelte.config.js
 
-This file contains your Svelte and SvelteKit [configuration](/docs/configuration).
+This file contains your Svelte and SvelteKit [configuration](configuration).
 
 ### tsconfig.json
 
@@ -80,10 +80,10 @@ This file (or `jsconfig.json`, if you prefer type-checked `.js` files over `.ts`
 
 ### vite.config.js
 
-A SvelteKit project is really just a [Vite](https://vitejs.dev) project that uses the [`@sveltejs/kit/vite`](/docs/modules#sveltejs-kit-vite) plugin, along with any other [Vite configuration](https://vitejs.dev/config/).
+A SvelteKit project is really just a [Vite](https://vitejs.dev) project that uses the [`@sveltejs/kit/vite`](modules#sveltejs-kit-vite) plugin, along with any other [Vite configuration](https://vitejs.dev/config/).
 
 ## Other files
 
 ### .svelte-kit
 
-As you develop and build your project, SvelteKit will generate files in a `.svelte-kit` directory (configurable as [`outDir`](/docs/configuration#outdir)). You can ignore its contents, and delete them at any time (they will be regenerated when you next `dev` or `build`).
+As you develop and build your project, SvelteKit will generate files in a `.svelte-kit` directory (configurable as [`outDir`](configuration#outdir)). You can ignore its contents, and delete them at any time (they will be regenerated when you next `dev` or `build`).
diff --git a/documentation/docs/10-getting-started/40-web-standards.md b/documentation/docs/10-getting-started/40-web-standards.md
index a12f534cf..949b5b617 100644
--- a/documentation/docs/10-getting-started/40-web-standards.md
+++ b/documentation/docs/10-getting-started/40-web-standards.md
@@ -4,21 +4,21 @@ title: Web standards
 
 Throughout this documentation, you'll see references to the standard [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) that SvelteKit builds on top of. Rather than reinventing the wheel, we _use the platform_, which means your existing web development skills are applicable to SvelteKit. Conversely, time spent learning SvelteKit will help you be a better web developer elsewhere.
 
-These APIs are available in all modern browsers and in many non-browser environments like Cloudflare Workers, Deno and Vercel Edge Functions. During development, and in [adapters](/docs/adapters) for Node-based environments (including AWS Lambda), they're made available via polyfills where necessary (for now, that is — Node is rapidly adding support for more web standards).
+These APIs are available in all modern browsers and in many non-browser environments like Cloudflare Workers, Deno and Vercel Edge Functions. During development, and in [adapters](adapters) for Node-based environments (including AWS Lambda), they're made available via polyfills where necessary (for now, that is — Node is rapidly adding support for more web standards).
 
 In particular, you'll get comfortable with the following:
 
 ## Fetch APIs
 
-SvelteKit uses [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) for getting data from the network. It's available in [hooks](/docs/hooks) and [server routes](/docs/routing#server) as well as in the browser.
+SvelteKit uses [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) for getting data from the network. It's available in [hooks](hooks) and [server routes](routing#server) as well as in the browser.
 
-> A special version of `fetch` is available in [`load`](/docs/load) functions, [server hooks](/docs/hooks#server-hooks) and [API routes](/docs/routing#server) for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. (To make credentialled fetches in server-side code outside `load`, you must explicitly pass `cookie` and/or `authorization` headers.) It also allows you to make relative requests, whereas server-side `fetch` normally requires a fully qualified URL.
+> A special version of `fetch` is available in [`load`](load) functions, [server hooks](hooks#server-hooks) and [API routes](routing#server) for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. (To make credentialled fetches in server-side code outside `load`, you must explicitly pass `cookie` and/or `authorization` headers.) It also allows you to make relative requests, whereas server-side `fetch` normally requires a fully qualified URL.
 
 Besides `fetch` itself, the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) includes the following interfaces:
 
 ### Request
 
-An instance of [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) is accessible in [hooks](/docs/hooks) and [server routes](/docs/routing#server) as `event.request`. It contains useful methods like `request.json()` and `request.formData()` for getting data that was posted to an endpoint.
+An instance of [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) is accessible in [hooks](hooks) and [server routes](routing#server) as `event.request`. It contains useful methods like `request.json()` and `request.formData()` for getting data that was posted to an endpoint.
 
 ### Response
 
@@ -74,7 +74,7 @@ Most of the time, your endpoints will return complete data, as in the `userAgent
 
 ## URL APIs
 
-URLs are represented by the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) interface, which includes useful properties like `origin` and `pathname` (and, in the browser, `hash`). This interface shows up in various places — `event.url` in [hooks](/docs/hooks) and [server routes](/docs/routing#server), [`$page.url`](/docs/modules#$app-stores) in [pages](/docs/routing#page), `from` and `to` in [`beforeNavigate` and `afterNavigate`](/docs/modules#$app-navigation) and so on.
+URLs are represented by the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) interface, which includes useful properties like `origin` and `pathname` (and, in the browser, `hash`). This interface shows up in various places — `event.url` in [hooks](hooks) and [server routes](routing#server), [`$page.url`](modules#$app-stores) in [pages](routing#page), `from` and `to` in [`beforeNavigate` and `afterNavigate`](modules#$app-navigation) and so on.
 
 ### URLSearchParams
 
@@ -95,7 +95,7 @@ const foo = url.searchParams.get('foo');
 
 ## Web Crypto
 
-The [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is made available via the `crypto` global. It's used internally for [Content Security Policy](/docs/configuration#csp) headers, but you can also use it for things like generating UUIDs:
+The [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is made available via the `crypto` global. It's used internally for [Content Security Policy](configuration#csp) headers, but you can also use it for things like generating UUIDs:
 
 ```js
 const uuid = crypto.randomUUID();
diff --git a/documentation/docs/20-core-concepts/10-routing.md b/documentation/docs/20-core-concepts/10-routing.md
index e1e20da88..7f1f89906 100644
--- a/documentation/docs/20-core-concepts/10-routing.md
+++ b/documentation/docs/20-core-concepts/10-routing.md
@@ -8,7 +8,7 @@ At the heart of SvelteKit is a _filesystem-based router_. The routes of your app
 - `src/routes/about` creates an `/about` route
 - `src/routes/blog/[slug]` creates a route with a _parameter_, `slug`, that can be used to load data dynamically when a user requests a page like `/blog/hello-world`
 
-> You can change `src/routes` to a different directory by editing the [project config](/docs/configuration).
+> You can change `src/routes` to a different directory by editing the [project config](configuration).
 
 Each route directory contains one or more _route files_, which can be identified by their `+` prefix.
 
@@ -16,7 +16,7 @@ Each route directory contains one or more _route files_, which can be identified
 
 ### +page.svelte
 
-A `+page.svelte` component defines a page of your app. By default, pages are rendered both on the server ([SSR](/docs/glossary#ssr)) for the initial request and in the browser ([CSR](/docs/glossary#csr)) for subsequent navigation.
+A `+page.svelte` component defines a page of your app. By default, pages are rendered both on the server ([SSR](glossary#ssr)) for the initial request and in the browser ([CSR](glossary#csr)) for subsequent navigation.
 
 ```svelte
 /// file: src/routes/+page.svelte
@@ -65,7 +65,7 @@ export function load({ params }) {
 }
 ```
 
-This function runs alongside `+page.svelte`, which means it runs on the server during server-side rendering and in the browser during client-side navigation. See [`load`](/docs/load) for full details of the API.
+This function runs alongside `+page.svelte`, which means it runs on the server during server-side rendering and in the browser during client-side navigation. See [`load`](load) for full details of the API.
 
 As well as `load`, `+page.js` can export values that configure the page's behaviour:
 
@@ -73,11 +73,11 @@ As well as `load`, `+page.js` can export values that configure the page's behavi
 - `export const ssr = true` or `false`
 - `export const csr = true` or `false`
 
-You can find more information about these in [page options](/docs/page-options).
+You can find more information about these in [page options](page-options).
 
 ### +page.server.js
 
-If your `load` function can only run on the server — for example, if it needs to fetch data from a database or you need to access private [environment variables](/docs/modules#$env-static-private) like API keys — then you can rename `+page.js` to `+page.server.js` and change the `PageLoad` type to `PageServerLoad`.
+If your `load` function can only run on the server — for example, if it needs to fetch data from a database or you need to access private [environment variables](modules#$env-static-private) like API keys — then you can rename `+page.js` to `+page.server.js` and change the `PageLoad` type to `PageServerLoad`.
 
 ```js
 /// file: src/routes/blog/[slug]/+page.server.js
@@ -108,11 +108,11 @@ export async function load({ params }) {
 }
 ```
 
-During client-side navigation, SvelteKit will load this data from the server, which means that the returned value must be serializable using [devalue](https://github.com/rich-harris/devalue). See [`load`](/docs/load) for full details of the API.
+During client-side navigation, SvelteKit will load this data from the server, which means that the returned value must be serializable using [devalue](https://github.com/rich-harris/devalue). See [`load`](load) for full details of the API.
 
-Like `+page.js`, `+page.server.js` can export [page options](/docs/page-options) — `prerender`, `ssr` and `csr`.
+Like `+page.js`, `+page.server.js` can export [page options](page-options) — `prerender`, `ssr` and `csr`.
 
-A `+page.server.js` file can also export _actions_. If `load` lets you read data from the server, `actions` let you write data _to_ the server using the `<form>` element. To learn how to use them, see the [form actions](/docs/form-actions) section.
+A `+page.server.js` file can also export _actions_. If `load` lets you read data from the server, `actions` let you write data _to_ the server using the `<form>` element. To learn how to use them, see the [form actions](form-actions) section.
 
 ## +error
 
@@ -133,9 +133,9 @@ If the error occurs inside a `load` function in `+layout(.server).js`, the close
 
 If no route can be found (404), `src/routes/+error.svelte` (or the default error page, if that file does not exist) will be used.
 
-> `+error.svelte` is _not_ used when an error occurs inside [`handle`](/docs/hooks#server-hooks-handle) or a [+server.js](#server) request handler.
+> `+error.svelte` is _not_ used when an error occurs inside [`handle`](hooks#server-hooks-handle) or a [+server.js](#server) request handler.
 
-You can read more about error handling [here](/docs/errors).
+You can read more about error handling [here](errors).
 
 ## +layout
 
@@ -205,11 +205,11 @@ We can create a layout that only applies to pages below `/settings` (while inher
 <slot></slot>
 ```
 
-By default, each layout inherits the layout above it. Sometimes that isn't what you want - in this case, [advanced layouts](/docs/advanced-routing#advanced-layouts) can help you.
+By default, each layout inherits the layout above it. Sometimes that isn't what you want - in this case, [advanced layouts](advanced-routing#advanced-layouts) can help you.
 
 ### +layout.js
 
-Just like `+page.svelte` loading data from `+page.js`, your `+layout.svelte` component can get data from a [`load`](/docs/load) function in `+layout.js`.
+Just like `+page.svelte` loading data from `+page.js`, your `+layout.svelte` component can get data from a [`load`](load) function in `+layout.js`.
 
 ```js
 /// file: src/routes/settings/+layout.js
@@ -224,7 +224,7 @@ export function load() {
 }
 ```
 
-If a `+layout.js` exports [page options](/docs/page-options) — `prerender`, `ssr` and `csr` — they will be used as defaults for child pages.
+If a `+layout.js` exports [page options](page-options) — `prerender`, `ssr` and `csr` — they will be used as defaults for child pages.
 
 Data returned from a layout's `load` function is also available to all its child pages:
 
@@ -238,13 +238,13 @@ Data returned from a layout's `load` function is also available to all its child
 </script>
 ```
 
-> Often, layout data is unchanged when navigating between pages. SvelteKit will intelligently re-run [`load`](/docs/load) functions when necessary.
+> Often, layout data is unchanged when navigating between pages. SvelteKit will intelligently re-run [`load`](load) functions when necessary.
 
 ### +layout.server.js
 
 To run your layout's `load` function on the server, move it to `+layout.server.js`, and change the `LayoutLoad` type to `LayoutServerLoad`.
 
-Like `+layout.js`, `+layout.server.js` can export [page options](/docs/page-options) — `prerender`, `ssr` and `csr`.
+Like `+layout.js`, `+layout.server.js` can export [page options](page-options) — `prerender`, `ssr` and `csr`.
 
 ## +server
 
@@ -275,9 +275,9 @@ export function GET({ url }) {
 
 The first argument to `Response` can be a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream), making it possible to stream large amounts of data or create server-sent events (unless deploying to platforms that buffer responses, like AWS Lambda).
 
-You can use the [`error`](/docs/modules#sveltejs-kit-error), [`redirect`](/docs/modules#sveltejs-kit-redirect) and [`json`](/docs/modules#sveltejs-kit-json) methods from `@sveltejs/kit` for convenience (but you don't have to).
+You can use the [`error`](modules#sveltejs-kit-error), [`redirect`](modules#sveltejs-kit-redirect) and [`json`](modules#sveltejs-kit-json) methods from `@sveltejs/kit` for convenience (but you don't have to).
 
-If an error is thrown (either `throw error(...)` or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. The [`+error.svelte`](#error) component will _not_ be rendered in this case. You can read more about error handling [here](/docs/errors).
+If an error is thrown (either `throw error(...)` or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. The [`+error.svelte`](#error) component will _not_ be rendered in this case. You can read more about error handling [here](errors).
 
 ### Receiving data
 
@@ -321,7 +321,7 @@ export async function POST({ request }) {
 }
 ```
 
-> In general, [form actions](/docs/form-actions) are a better way to submit data from the browser to the server.
+> In general, [form actions](form-actions) are a better way to submit data from the browser to the server.
 
 ### Content negotiation
 
@@ -350,4 +350,4 @@ In turn, annotating the `load` function with `PageLoad`, `PageServerLoad`, `Layo
 
 Any other files inside a route directory are ignored by SvelteKit. This means you can colocate components and utility modules with the routes that need them.
 
-If components and modules are needed by multiple routes, it's a good idea to put them in [`$lib`](/docs/modules#$lib).
+If components and modules are needed by multiple routes, it's a good idea to put them in [`$lib`](modules#$lib).
diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md
index 3df805300..b1e80fb15 100644
--- a/documentation/docs/20-core-concepts/20-load.md
+++ b/documentation/docs/20-core-concepts/20-load.md
@@ -2,7 +2,7 @@
 title: Loading data
 ---
 
-Before a [`+page.svelte`](/docs/routing#page-page-svelte) component (and its containing [`+layout.svelte`](/docs/routing#layout-layout-svelte) components) can be rendered, we often need to get some data. This is done by defining `load` functions.
+Before a [`+page.svelte`](routing#page-page-svelte) component (and its containing [`+layout.svelte`](routing#layout-layout-svelte) components) can be rendered, we often need to get some data. This is done by defining `load` functions.
 
 ## Page data
 
@@ -57,7 +57,7 @@ export async function load({ params }) {
 }
 ```
 
-Notice that the type changed from `PageLoad` to `PageServerLoad`, because server `load` functions can access additional arguments. To understand when to use `+page.js` and when to use `+page.server.js`, see [Universal vs server](/docs/load#universal-vs-server).
+Notice that the type changed from `PageLoad` to `PageServerLoad`, because server `load` functions can access additional arguments. To understand when to use `+page.js` and when to use `+page.server.js`, see [Universal vs server](load#universal-vs-server).
 
 ## Layout data
 
@@ -192,7 +192,7 @@ Often the `load` function depends on the URL in one way or another. For this, th
 
 An instance of [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL), containing properties like the `origin`, `hostname`, `pathname` and `searchParams` (which contains the parsed query string as a [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object). `url.hash` cannot be accessed during `load`, since it is unavailable on the server.
 
-> In some environments this is derived from request headers during server-side rendering. If you're using [adapter-node](/docs/adapter-node), for example, you may need to configure the adapter in order for the URL to be correct.
+> In some environments this is derived from request headers during server-side rendering. If you're using [adapter-node](adapter-node), for example, you may need to configure the adapter in order for the URL to be correct.
 
 ### route
 
@@ -226,7 +226,7 @@ To get data from an external API or a `+server.js` handler, you can use the prov
 - it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request
 - it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)
 - internal requests (e.g. for `+server.js` routes) go direct to the handler function when running on the server, without the overhead of an HTTP call
-- during server-side rendering, the response will be captured and inlined into the rendered HTML. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](/docs/hooks#server-hooks-handle). Then, during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request - if you got a warning in your browser console when using the browser `fetch` instead of the `load` `fetch`, this is why.
+- during server-side rendering, the response will be captured and inlined into the rendered HTML. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](hooks#server-hooks-handle). Then, during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request - if you got a warning in your browser console when using the browser `fetch` instead of the `load` `fetch`, this is why.
 
 ```js
 /// file: src/routes/items/[id]/+page.js
@@ -243,7 +243,7 @@ export async function load({ fetch, params }) {
 
 ## Cookies and headers
 
-A server `load` function can get and set [`cookies`](/docs/types#public-types-cookies).
+A server `load` function can get and set [`cookies`](types#public-types-cookies).
 
 ```js
 /// file: src/routes/+layout.server.js
@@ -356,7 +356,7 @@ export async function load({ params, parent }) {
 
 ## Errors
 
-If an error is thrown during `load`, the nearest [`+error.svelte`](/docs/routing#error) will be rendered. For _expected_ errors, use the `error` helper from `@sveltejs/kit` to specify the HTTP status code and an optional message:
+If an error is thrown during `load`, the nearest [`+error.svelte`](routing#error) will be rendered. For _expected_ errors, use the `error` helper from `@sveltejs/kit` to specify the HTTP status code and an optional message:
 
 ```js
 /// file: src/routes/admin/+layout.server.js
@@ -386,7 +386,7 @@ export function load({ locals }) {
 }
 ```
 
-If an _unexpected_ error is thrown, SvelteKit will invoke [`handleError`](/docs/hooks#shared-hooks-handleerror) and treat it as a 500 Internal Error.
+If an _unexpected_ error is thrown, SvelteKit will invoke [`handleError`](hooks#shared-hooks-handleerror) and treat it as a 500 Internal Error.
 
 ## Redirects
 
@@ -498,7 +498,7 @@ A `load` function that calls `await parent()` will also re-run if a parent `load
 
 ### Manual invalidation
 
-You can also re-run `load` functions that apply to the current page using [`invalidate(url)`](/docs/modules#$app-navigation-invalidate), which re-runs all `load` functions that depend on `url`, and [`invalidateAll()`](/docs/modules#$app-navigation-invalidateall), which re-runs every `load` function.
+You can also re-run `load` functions that apply to the current page using [`invalidate(url)`](modules#$app-navigation-invalidate), which re-runs all `load` functions that depend on `url`, and [`invalidateAll()`](modules#$app-navigation-invalidateall), which re-runs every `load` function.
 
 A `load` function depends on `url` if it calls `fetch(url)` or `depends(url)`. Note that `url` can be a custom identifier that starts with `[a-z]:`:
 
@@ -544,10 +544,10 @@ To summarize, a `load` function will re-run in the following situations:
 - It references a property of `params` whose value has changed
 - It references a property of `url` (such as `url.pathname` or `url.search`) whose value has changed
 - It calls `await parent()` and a parent `load` function re-ran
-- It declared a dependency on a specific URL via [`fetch`](#making-fetch-requests) or [`depends`](/docs/types#public-types-loadevent), and that URL was marked invalid with [`invalidate(url)`](/docs/modules#$app-navigation-invalidate)
-- All active `load` functions were forcibly re-run with [`invalidateAll()`](/docs/modules#$app-navigation-invalidateall)
+- It declared a dependency on a specific URL via [`fetch`](#making-fetch-requests) or [`depends`](types#public-types-loadevent), and that URL was marked invalid with [`invalidate(url)`](modules#$app-navigation-invalidate)
+- All active `load` functions were forcibly re-run with [`invalidateAll()`](modules#$app-navigation-invalidateall)
 
-Note that re-running a `load` function will update the `data` prop inside the corresponding `+layout.svelte` or `+page.svelte`; it does _not_ cause the component to be recreated. As a result, internal state is preserved. If this isn't what you want, you can reset whatever you need to reset inside an [`afterNavigate`](/docs/modules#$app-navigation-afternavigate) callback, and/or wrap your component in a [`{#key ...}`](https://svelte.dev/docs#template-syntax-key) block.
+Note that re-running a `load` function will update the `data` prop inside the corresponding `+layout.svelte` or `+page.svelte`; it does _not_ cause the component to be recreated. As a result, internal state is preserved. If this isn't what you want, you can reset whatever you need to reset inside an [`afterNavigate`](modules#$app-navigation-afternavigate) callback, and/or wrap your component in a [`{#key ...}`](https://svelte.dev/docs#template-syntax-key) block.
 
 ## Shared state
 
diff --git a/documentation/docs/20-core-concepts/30-form-actions.md b/documentation/docs/20-core-concepts/30-form-actions.md
index f135a5043..b5ba00b99 100644
--- a/documentation/docs/20-core-concepts/30-form-actions.md
+++ b/documentation/docs/20-core-concepts/30-form-actions.md
@@ -209,7 +209,7 @@ The returned data must be serializable as JSON. Beyond that, the structure is en
 
 ### Redirects
 
-Redirects (and errors) work exactly the same as in [`load`](/docs/load#redirects):
+Redirects (and errors) work exactly the same as in [`load`](load#redirects):
 
 ```diff
 /// file: src/routes/login/+page.server.js
@@ -337,7 +337,7 @@ Without an argument, `use:enhance` will emulate the browser-native behaviour, ju
 - reset the `<form>` element and invalidate all data using `invalidateAll` on a successful response
 - call `goto` on a redirect response
 - render the nearest `+error` boundary if an error occurs
-- [reset focus](/docs/accessibility#focus-management) to the appropriate element
+- [reset focus](accessibility#focus-management) to the appropriate element
 
 To customise the behaviour, you can provide a `SubmitFunction` that runs immediately before the form is submitted, and (optionally) returns a callback that runs with the `ActionResult`. Note that if you return a callback, the default behavior mentioned above is not triggered. To get it back, call `update`.
 
@@ -396,7 +396,7 @@ The behaviour of `applyAction(result)` depends on `result.type`:
 - `redirect` — calls `goto(result.location)`
 - `error` — renders the nearest `+error` boundary with `result.error`
 
-In all cases, [focus will be reset](/docs/accessibility#focus-management).
+In all cases, [focus will be reset](accessibility#focus-management).
 
 ### Custom event listener
 
@@ -455,7 +455,7 @@ const response = await fetch(this.action, {
 
 ## Alternatives
 
-Form actions are the preferred way to send data to the server, since they can be progressively enhanced, but you can also use [`+server.js`](/docs/routing#server) files to expose (for example) a JSON API.
+Form actions are the preferred way to send data to the server, since they can be progressively enhanced, but you can also use [`+server.js`](routing#server) files to expose (for example) a JSON API.
 
 ## GET vs POST
 
@@ -472,4 +472,4 @@ Some forms don't need to `POST` data to the server — search inputs, for exampl
 </form>
 ```
 
-As with `<a>` elements, you can set the [`data-sveltekit-reload`](/docs/link-options#data-sveltekit-reload) and [`data-sveltekit-noscroll`](/docs/link-options#data-sveltekit-noscroll) attributes on the `<form>` to control the router's behaviour.
+As with `<a>` elements, you can set the [`data-sveltekit-reload`](link-options#data-sveltekit-reload) and [`data-sveltekit-noscroll`](link-options#data-sveltekit-noscroll) attributes on the `<form>` to control the router's behaviour.
diff --git a/documentation/docs/20-core-concepts/40-page-options.md b/documentation/docs/20-core-concepts/40-page-options.md
index 32182423b..78f23a9c2 100644
--- a/documentation/docs/20-core-concepts/40-page-options.md
+++ b/documentation/docs/20-core-concepts/40-page-options.md
@@ -2,15 +2,15 @@
 title: Page options
 ---
 
-By default, SvelteKit will render (or [prerender](/docs/glossary#prerendering)) any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called [**hydration**](/docs/glossary#hydration). For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a [**router**](/docs/routing) that takes over subsequent navigations.
+By default, SvelteKit will render (or [prerender](glossary#prerendering)) any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called [**hydration**](glossary#hydration). For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a [**router**](routing) that takes over subsequent navigations.
 
-You can control each of these on a page-by-page basis by exporting options from [`+page.js`](/docs/routing#page-page-js) or [`+page.server.js`](/docs/routing#page-page-server-js), or for groups of pages using a shared [`+layout.js`](/docs/routing#layout-layout-js) or [`+layout.server.js`](/docs/routing#layout-layout-server-js). To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered.
+You can control each of these on a page-by-page basis by exporting options from [`+page.js`](routing#page-page-js) or [`+page.server.js`](routing#page-page-server-js), or for groups of pages using a shared [`+layout.js`](routing#layout-layout-js) or [`+layout.server.js`](routing#layout-layout-server-js). To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered.
 
 You can mix and match these options in different areas of your app. For example you could prerender your marketing page for maximum speed, server-render your dynamic pages for SEO and accessibility and turn your admin section into an SPA by rendering it on the client only. This makes SvelteKit very versatile.
 
 ## prerender
 
-It's likely that at least some routes of your app can be represented as a simple HTML file generated at build time. These routes can be [_prerendered_](/docs/glossary#prerendering).
+It's likely that at least some routes of your app can be represented as a simple HTML file generated at build time. These routes can be [_prerendered_](glossary#prerendering).
 
 ```js
 /// file: +page.js/+page.server.js/+server.js
@@ -33,9 +33,9 @@ export const prerender = 'auto';
 
 > 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 files for any prerenderable pages or `+server.js` routes it finds. Each page is scanned for `<a>` 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).
+The prerenderer will start at the root of your app and generate files for any prerenderable pages or `+server.js` routes it finds. Each page is scanned for `<a>` 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](configuration#prerender).
 
-While prerendering, the value of `building` imported from [`$app/environment`](/docs/modules#$app-environment) will be `true`.
+While prerendering, the value of `building` imported from [`$app/environment`](modules#$app-environment) will be `true`.
 
 ### Prerendering server routes
 
@@ -62,9 +62,9 @@ The basic rule is this: for a page to be prerenderable, any two users hitting it
 
 Note that you can still prerender pages that load data based on the page's parameters, such as a `src/routes/blog/[slug]/+page.svelte` route.
 
-Accessing [`url.searchParams`](/docs/load#using-url-data-url) during prerendering is forbidden. If you need to use it, ensure you are only doing so in the browser (for example in `onMount`).
+Accessing [`url.searchParams`](load#using-url-data-url) during prerendering is forbidden. If you need to use it, ensure you are only doing so in the browser (for example in `onMount`).
 
-Pages with [actions](/docs/form-actions) cannot be prerendered, because a server must be able to handle the action `POST` requests.
+Pages with [actions](form-actions) cannot be prerendered, because a server must be able to handle the action `POST` requests.
 
 ### Prerender and ssr
 
@@ -86,12 +86,12 @@ If you encounter an error like 'The following routes were marked as prerenderabl
 
 Since these routes cannot be dynamically server-rendered, this will cause errors when people try to access the route in question. There are two ways to fix it:
 
-* Ensure that SvelteKit can find the route by following links from [`config.kit.prerender.entries`](/docs/configuration#prerender). Add links to dynamic routes (i.e. pages with `[parameters]` ) to this option if they are not found through crawling the other entry points, else they are not prerendered because SvelteKit doesn't know what value the parameters should have. Pages not marked as prerenderable will be ignored and their links to other pages will not be crawled, even if some of them would be prerenderable.
+* Ensure that SvelteKit can find the route by following links from [`config.kit.prerender.entries`](configuration#prerender). Add links to dynamic routes (i.e. pages with `[parameters]` ) to this option if they are not found through crawling the other entry points, else they are not prerendered because SvelteKit doesn't know what value the parameters should have. Pages not marked as prerenderable will be ignored and their links to other pages will not be crawled, even if some of them would be prerenderable.
 * Change `export const prerender = true` to `export const prerender = 'auto'`. Routes with `'auto'` can be dynamically server rendered
 
 ## ssr
 
-Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's [hydrated](/docs/glossary#hydration). If you set `ssr` to `false`, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server (because you use browser-only globals like `document` for example), but in most situations it's not recommended ([see appendix](/docs/glossary#ssr)).
+Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's [hydrated](glossary#hydration). If you set `ssr` to `false`, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server (because you use browser-only globals like `document` for example), but in most situations it's not recommended ([see appendix](glossary#ssr)).
 
 ```js
 /// file: +page.js
@@ -102,7 +102,7 @@ If you add `export const ssr = false` to your root `+layout.js`, your entire app
 
 ## csr
 
-Ordinarily, SvelteKit [hydrates](/docs/glossary#hydration) your server-rendered HTML into an interactive client-side-rendered (CSR) page. Some pages don't require JavaScript at all — many blog posts and 'about' pages fall into this category. In these cases you can disable CSR:
+Ordinarily, SvelteKit [hydrates](glossary#hydration) your server-rendered HTML into an interactive client-side-rendered (CSR) page. Some pages don't require JavaScript at all — many blog posts and 'about' pages fall into this category. In these cases you can disable CSR:
 
 ```js
 /// file: +page.js
diff --git a/documentation/docs/25-build-and-deploy/10-building-your-app.md b/documentation/docs/25-build-and-deploy/10-building-your-app.md
index 60005f696..d7c4cb71b 100644
--- a/documentation/docs/25-build-and-deploy/10-building-your-app.md
+++ b/documentation/docs/25-build-and-deploy/10-building-your-app.md
@@ -4,13 +4,13 @@ title: Building your app
 
 Building a SvelteKit app happens in two stages, which both happen when you run `vite build` (usually via `npm run build`).
 
-Firstly, Vite creates an optimized production build of your server code, your browser code, and your service worker (if you have one). [Prerendering](/docs/page-options#prerender) is executed at this stage, if appropriate.
+Firstly, Vite creates an optimized production build of your server code, your browser code, and your service worker (if you have one). [Prerendering](page-options#prerender) is executed at this stage, if appropriate.
 
 Secondly, an _adapter_ takes this production build and tunes it for your target environment — more on this on the following pages.
 
 ## During the build
 
-SvelteKit will load your `+page/layout(.server).js` files (and all files they import) for analysis during the build. Any code that should _not_ be executed at this stage must check that `building` from [`$app/environment`](/docs/modules#$app-environment) is `false`:
+SvelteKit will load your `+page/layout(.server).js` files (and all files they import) for analysis during the build. Any code that should _not_ be executed at this stage must check that `building` from [`$app/environment`](modules#$app-environment) is `false`:
 
 ```diff
 +import { building } from '$app/environment';
diff --git a/documentation/docs/25-build-and-deploy/20-adapters.md b/documentation/docs/25-build-and-deploy/20-adapters.md
index 815cfab70..15acd012f 100644
--- a/documentation/docs/25-build-and-deploy/20-adapters.md
+++ b/documentation/docs/25-build-and-deploy/20-adapters.md
@@ -45,5 +45,5 @@ export default config;
 
 ## Platform-specific context
 
-Some adapters may have access to additional information about the request. For example, Cloudflare Workers can access an `env` object containing KV namespaces etc. This can be passed to the `RequestEvent` used in [hooks](/docs/hooks) and [server routes](/docs/routing#server) as the `platform` property — consult each adapter's documentation to learn more.
+Some adapters may have access to additional information about the request. For example, Cloudflare Workers can access an `env` object containing KV namespaces etc. This can be passed to the `RequestEvent` used in [hooks](hooks) and [server routes](routing#server) as the `platform` property — consult each adapter's documentation to learn more.
 
diff --git a/documentation/docs/25-build-and-deploy/40-adapter-node.md b/documentation/docs/25-build-and-deploy/40-adapter-node.md
index 8ca23baa7..f5c10b45f 100644
--- a/documentation/docs/25-build-and-deploy/40-adapter-node.md
+++ b/documentation/docs/25-build-and-deploy/40-adapter-node.md
@@ -71,13 +71,13 @@ PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build
 
 > [`x-forwarded-proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) and [`x-forwarded-host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) are de facto standard headers that forward the original protocol and host if you're using a reverse proxy (think load balancers and CDNs). You should only set these variables if your server is behind a trusted reverse proxy; otherwise, it'd be possible for clients to spoof these headers.
 
-If `adapter-node` can't correctly determine the URL of your deployment, you may experience this error when using [form actions](/docs/form-actions):
+If `adapter-node` can't correctly determine the URL of your deployment, you may experience this error when using [form actions](form-actions):
 
 > Cross-site POST form submissions are forbidden
 
 ### `ADDRESS_HEADER` and `XFF_DEPTH`
 
-The [RequestEvent](/docs/types#public-types-requestevent) object passed to hooks and endpoints includes an `event.getClientAddress()` function that returns the client's IP address. By default this is the connecting `remoteAddress`. If your server is behind one or more proxies (such as a load balancer), this value will contain the innermost proxy's IP address rather than the client's, so we need to specify an `ADDRESS_HEADER` to read the address from:
+The [RequestEvent](types#public-types-requestevent) object passed to hooks and endpoints includes an `event.getClientAddress()` function that returns the client's IP address. By default this is the connecting `remoteAddress`. If your server is behind one or more proxies (such as a load balancer), this value will contain the innermost proxy's IP address rather than the client's, so we need to specify an `ADDRESS_HEADER` to read the address from:
 
 ```
 ADDRESS_HEADER=True-Client-IP node build
@@ -103,7 +103,7 @@ We instead read from the _right_, accounting for the number of trusted proxies.
 
 ### `BODY_SIZE_LIMIT`
 
-The maximum request body size to accept in bytes including while streaming. Defaults to 512kb. You can disable this option with a value of 0 and implement a custom check in [`handle`](/docs/hooks#server-hooks-handle) if you need something more advanced.
+The maximum request body size to accept in bytes including while streaming. Defaults to 512kb. You can disable this option with a value of 0 and implement a custom check in [`handle`](hooks#server-hooks-handle) if you need something more advanced.
 
 ## Options
 
diff --git a/documentation/docs/25-build-and-deploy/50-adapter-static.md b/documentation/docs/25-build-and-deploy/50-adapter-static.md
index cd2ce0566..be7d85434 100644
--- a/documentation/docs/25-build-and-deploy/50-adapter-static.md
+++ b/documentation/docs/25-build-and-deploy/50-adapter-static.md
@@ -4,7 +4,7 @@ title: Static site generation
 
 To use SvelteKit as a static site generator (SSG), use [`adapter-static`](https://github.com/sveltejs/kit/tree/master/packages/adapter-static).
 
-This will prerender your entire site as a collection of static files. If you'd like to prerender only some pages, you will need to use a different adapter together with [the `prerender` option](/docs/page-options#prerender).
+This will prerender your entire site as a collection of static files. If you'd like to prerender only some pages, you will need to use a different adapter together with [the `prerender` option](page-options#prerender).
 
 ## Usage
 
@@ -30,7 +30,7 @@ export default {
 };
 ```
 
-...and add the [`prerender`](/docs/page-options#prerender) option to your root layout:
+...and add the [`prerender`](page-options#prerender) option to your root layout:
 
 ```js
 /// file: src/routes/+layout.js
@@ -38,7 +38,7 @@ export default {
 export const prerender = true;
 ```
 
-> You must ensure SvelteKit's [`trailingSlash`](/docs/page-options#trailingslash) option is set appropriately for your environment. If your host does not render `/a.html` upon receiving a request for `/a` then you will need to set `trailingSlash: 'always'` to create `/a/index.html` instead.
+> You must ensure SvelteKit's [`trailingSlash`](page-options#trailingslash) option is set appropriately for your environment. If your host does not render `/a.html` upon receiving a request for `/a` then you will need to set `trailingSlash: 'always'` to create `/a/index.html` instead.
 
 ## Zero-config support
 
@@ -135,7 +135,7 @@ export default {
 
 ### Turn off prerendering
 
-When operating in SPA mode, you can omit the [`prerender`](/docs/page-options#prerender) option from your root layout (or set it to `false`, its default value), and only pages that have the `prerender` option set will be prerendered at build time.
+When operating in SPA mode, you can omit the [`prerender`](page-options#prerender) option from your root layout (or set it to `false`, its default value), and only pages that have the `prerender` option set will be prerendered at build time.
 
 SvelteKit will still crawl your app's entry points looking for prerenderable pages. If `svelte-kit build` fails because of pages that can't be loaded outside the browser, you can set `config.kit.prerender.entries` to `[]` to prevent this from happening. (Setting `config.kit.prerender.enabled` to `false` also has this effect, but would prevent the fallback page from being generated.)
 
@@ -143,7 +143,7 @@ You can also add turn off prerendering only to parts of your app, if you want ot
 
 ### Turn off ssr
 
-During development, SvelteKit will still attempt to server-side render your routes. This means accessing things that are only available in the browser (such as the `window` object) will result in errors, even though this would be valid in the output app. To align the behavior of SvelteKit's dev mode with your SPA, you can [add `export const ssr = false` to your root `+layout`](/docs/page-options#ssr). You can also add this option only to parts of your app, if you want other parts to be prerendered.
+During development, SvelteKit will still attempt to server-side render your routes. This means accessing things that are only available in the browser (such as the `window` object) will result in errors, even though this would be valid in the output app. To align the behavior of SvelteKit's dev mode with your SPA, you can [add `export const ssr = false` to your root `+layout`](page-options#ssr). You can also add this option only to parts of your app, if you want other parts to be prerendered.
 
 ### Apache
 
@@ -162,7 +162,7 @@ To run an SPA on [Apache](https://httpd.apache.org/), you should add a `static/.
 
 ## GitHub Pages
 
-When building for GitHub Pages, make sure to update [`paths.base`](/docs/configuration#paths) to match your repo name, since the site will be served from <https://your-username.github.io/your-repo-name> rather than from the root.
+When building for GitHub Pages, make sure to update [`paths.base`](configuration#paths) to match your repo name, since the site will be served from <https://your-username.github.io/your-repo-name> rather than from the root.
 
 You will have to prevent GitHub's provided Jekyll from managing your site by putting an empty `.nojekyll` file in your static folder. If you do not want to disable Jekyll, change the kit's `appDir` configuration option to `'app_'` or anything not starting with an underscore. For more information, see GitHub's [Jekyll documentation](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll#configuring-jekyll-in-your-github-pages-site).
 
diff --git a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
index 50409446f..b51829a45 100644
--- a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
+++ b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
@@ -4,7 +4,7 @@ title: Cloudflare Pages
 
 To deploy to [Cloudflare Pages](https://developers.cloudflare.com/pages/), use [`adapter-cloudflare`](https://github.com/sveltejs/kit/tree/master/packages/adapter-cloudflare).
 
-This adapter will be installed by default when you use [`adapter-auto`](/docs/adapter-auto), but adding it to your project is recommended so that `event.platform` is automatically typed.
+This adapter will be installed by default when you use [`adapter-auto`](adapter-auto), but adding it to your project is recommended so that `event.platform` is automatically typed.
 
 ## Comparisons
 
diff --git a/documentation/docs/25-build-and-deploy/80-adapter-netlify.md b/documentation/docs/25-build-and-deploy/80-adapter-netlify.md
index 553f38b8e..21f734bf2 100644
--- a/documentation/docs/25-build-and-deploy/80-adapter-netlify.md
+++ b/documentation/docs/25-build-and-deploy/80-adapter-netlify.md
@@ -4,7 +4,7 @@ title: Netlify
 
 To deploy to Netlify, use [`adapter-netlify`](https://github.com/sveltejs/kit/tree/master/packages/adapter-netlify).
 
-This adapter will be installed by default when you use [`adapter-auto`](/docs/adapter-auto), but adding it to your project allows you to specify Netlify-specific options.
+This adapter will be installed by default when you use [`adapter-auto`](adapter-auto), but adding it to your project allows you to specify Netlify-specific options.
 
 ## Usage
 
diff --git a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
index d0161e1d5..94a050257 100644
--- a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
+++ b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
@@ -4,7 +4,7 @@ title: Vercel
 
 To deploy to Vercel, use [`adapter-vercel`](https://github.com/sveltejs/kit/tree/master/packages/adapter-vercel).
 
-This adapter will be installed by default when you use [`adapter-auto`](/docs/adapter-auto), but adding it to your project allows you to specify Vercel-specific options.
+This adapter will be installed by default when you use [`adapter-auto`](adapter-auto), but adding it to your project allows you to specify Vercel-specific options.
 
 ## Usage
 
diff --git a/documentation/docs/30-advanced/10-advanced-routing.md b/documentation/docs/30-advanced/10-advanced-routing.md
index 2c57e2c8f..6ba98e5bf 100644
--- a/documentation/docs/30-advanced/10-advanced-routing.md
+++ b/documentation/docs/30-advanced/10-advanced-routing.md
@@ -61,7 +61,7 @@ export function load(event) {
 }
 ```
 
-> If you don't handle 404 cases, they will appear in [`handleError`](/docs/hooks#shared-hooks-handleerror)
+> If you don't handle 404 cases, they will appear in [`handleError`](hooks#shared-hooks-handleerror)
 
 ## Optional parameters
 
@@ -71,7 +71,7 @@ Note that an optional route parameter cannot follow a rest parameter (`[...rest]
 
 ## Matching
 
-A route like `src/routes/archive/[page]` would match `/archive/3`, but it would also match `/archive/potato`. We don't want that. You can ensure that route parameters are well-formed by adding a _matcher_ — which takes the parameter string (`"3"` or `"potato"`) and returns `true` if it is valid — to your [`params`](/docs/configuration#files) directory...
+A route like `src/routes/archive/[page]` would match `/archive/3`, but it would also match `/archive/potato`. We don't want that. You can ensure that route parameters are well-formed by adding a _matcher_ — which takes the parameter string (`"3"` or `"potato"`) and returns `true` if it is valid — to your [`params`](configuration#files) directory...
 
 ```js
 /// file: src/params/integer.js
diff --git a/documentation/docs/30-advanced/20-hooks.md b/documentation/docs/30-advanced/20-hooks.md
index 6c3f5a1a3..def49a151 100644
--- a/documentation/docs/30-advanced/20-hooks.md
+++ b/documentation/docs/30-advanced/20-hooks.md
@@ -11,7 +11,7 @@ There are two hooks files, both optional:
 
 Code in these modules will run when the application starts up, making them useful for initializing database clients and so on.
 
-> You can configure the location of these files with [`config.kit.files.hooks`](/docs/configuration#files).
+> You can configure the location of these files with [`config.kit.files.hooks`](configuration#files).
 
 ## Server hooks
 
@@ -19,7 +19,7 @@ The following hooks can be added to `src/hooks.server.js`:
 
 ### handle
 
-This function runs every time the SvelteKit server receives a [request](/docs/web-standards#fetch-apis-request) — whether that happens while the app is running, or during [prerendering](/docs/page-options#prerender) — and determines the [response](/docs/web-standards#fetch-apis-response). It receives an `event` object representing the request and a function called `resolve`, which renders the route and generates a `Response`. This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
+This function runs every time the SvelteKit server receives a [request](web-standards#fetch-apis-request) — whether that happens while the app is running, or during [prerendering](page-options#prerender) — and determines the [response](web-standards#fetch-apis-response). It receives an `event` object representing the request and a function called `resolve`, which renders the route and generates a `Response`. This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
 
 ```js
 /// file: src/hooks.server.js
@@ -66,7 +66,7 @@ export async function handle({ event, resolve }) {
 }
 ```
 
-You can define multiple `handle` functions and execute them with [the `sequence` helper function](/docs/modules#sveltejs-kit-hooks).
+You can define multiple `handle` functions and execute them with [the `sequence` helper function](modules#sveltejs-kit-hooks).
 
 `resolve` also supports a second, optional parameter that gives you more control over how the response will be rendered. That parameter is an object that can have the following fields:
 
@@ -88,7 +88,7 @@ export async function handle({ event, resolve }) {
 }
 ```
 
-Note that `resolve(...)` will never throw an error, it will always return a `Promise<Response>` with the appropriate status code. If an error is thrown elsewhere during `handle`, it is treated as fatal, and SvelteKit will respond with a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. You can read more about error handling [here](/docs/errors).
+Note that `resolve(...)` will never throw an error, it will always return a `Promise<Response>` with the appropriate status code. If an error is thrown elsewhere during `handle`, it is treated as fatal, and SvelteKit will respond with a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. You can read more about error handling [here](errors).
 
 ### handleFetch
 
@@ -219,7 +219,7 @@ export function handleError({ error, event }) {
 
 > In `src/hooks.client.js`, the type of `handleError` is `HandleClientError` instead of `HandleServerError`, and `event` is a `NavigationEvent` rather than a `RequestEvent`.
 
-This function is not called for _expected_ errors (those thrown with the [`error`](/docs/modules#sveltejs-kit-error) function imported from `@sveltejs/kit`).
+This function is not called for _expected_ errors (those thrown with the [`error`](modules#sveltejs-kit-error) function imported from `@sveltejs/kit`).
 
 During development, if an error occurs because of a syntax error in your Svelte code, the passed in error has a `frame` property appended highlighting the location of the error.
 
diff --git a/documentation/docs/30-advanced/25-errors.md b/documentation/docs/30-advanced/25-errors.md
index 9932fa0b8..8f1c7b9e8 100644
--- a/documentation/docs/30-advanced/25-errors.md
+++ b/documentation/docs/30-advanced/25-errors.md
@@ -8,11 +8,11 @@ Errors are an inevitable fact of software development. SvelteKit handles errors
 
 SvelteKit distinguishes between expected and unexpected errors, both of which are represented as simple `{ message: string }` objects by default.
 
-You can add additional properties, like a `code` or a tracking `id`, as shown in the examples below. (When using TypeScript this requires you to redefine the `Error` type as described in  [type safety](/docs/errors#type-safety)).
+You can add additional properties, like a `code` or a tracking `id`, as shown in the examples below. (When using TypeScript this requires you to redefine the `Error` type as described in  [type safety](errors#type-safety)).
 
 ## Expected errors
 
-An _expected_ error is one created with the [`error`](/docs/modules#sveltejs-kit-error) helper imported from `@sveltejs/kit`:
+An _expected_ error is one created with the [`error`](modules#sveltejs-kit-error) helper imported from `@sveltejs/kit`:
 
 ```js
 /// file: src/routes/blog/[slug]/+page.server.js
@@ -40,7 +40,7 @@ export async function load({ params }) {
 }
 ```
 
-This tells SvelteKit to set the response status code to 404 and render an [`+error.svelte`](/docs/routing#error) component, where `$page.error` is the object provided as the second argument to `error(...)`.
+This tells SvelteKit to set the response status code to 404 and render an [`+error.svelte`](routing#error) component, where `$page.error` is the object provided as the second argument to `error(...)`.
 
 ```svelte
 /// file: src/routes/+error.svelte
@@ -77,7 +77,7 @@ By default, unexpected errors are printed to the console (or, in production, you
 { "message": "Internal Error" }
 ```
 
-Unexpected errors will go through the [`handleError`](/docs/hooks#shared-hooks-handleerror) hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object.
+Unexpected errors will go through the [`handleError`](hooks#shared-hooks-handleerror) hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object.
 
 ```js
 /// file: src/hooks.server.js
@@ -110,7 +110,7 @@ export function handleError({ error, event }) {
 
 ## Responses
 
-If an error occurs inside `handle` or inside a [`+server.js`](/docs/routing#server) request handler, SvelteKit will respond with either a fallback error page or a JSON representation of the error object, depending on the request's `Accept` headers.
+If an error occurs inside `handle` or inside a [`+server.js`](routing#server) request handler, SvelteKit will respond with either a fallback error page or a JSON representation of the error object, depending on the request's `Accept` headers.
 
 You can customise the fallback error page by adding a `src/error.html` file:
 
@@ -131,7 +131,7 @@ You can customise the fallback error page by adding a `src/error.html` file:
 
 SvelteKit will replace `%sveltekit.status%` and `%sveltekit.error.message%` with their corresponding values.
 
-If the error instead occurs inside a `load` function while rendering a page, SvelteKit will render the [`+error.svelte`](/docs/routing#error) component nearest to where the error occurred. If the error occurs inside a `load` function in `+layout(.server).js`, the closest error boundary in the tree is an `+error.svelte` file _above_ that layout (not next to it).
+If the error instead occurs inside a `load` function while rendering a page, SvelteKit will render the [`+error.svelte`](routing#error) component nearest to where the error occurred. If the error occurs inside a `load` function in `+layout(.server).js`, the closest error boundary in the tree is an `+error.svelte` file _above_ that layout (not next to it).
 
 The exception is when the error occurs inside the root `+layout.js` or `+layout.server.js`, since the root layout would ordinarily _contain_ the `+error.svelte` component. In this case, SvelteKit uses the fallback error page.
 
diff --git a/documentation/docs/30-advanced/30-link-options.md b/documentation/docs/30-advanced/30-link-options.md
index b4d5f9330..eb0db5ab0 100644
--- a/documentation/docs/30-advanced/30-link-options.md
+++ b/documentation/docs/30-advanced/30-link-options.md
@@ -64,7 +64,7 @@ Occasionally, we need to tell SvelteKit not to handle a link, but allow the brow
 
 ...will cause a full-page navigation when the link is clicked.
 
-Links with a `rel="external"` attribute will receive the same treatment. In addition, they will be ignored during [prerendering](/docs/page-options#prerender).
+Links with a `rel="external"` attribute will receive the same treatment. In addition, they will be ignored during [prerendering](page-options#prerender).
 
 ## data-sveltekit-noscroll
 
diff --git a/documentation/docs/30-advanced/40-service-workers.md b/documentation/docs/30-advanced/40-service-workers.md
index d0b74aa9a..09c1b8a8f 100644
--- a/documentation/docs/30-advanced/40-service-workers.md
+++ b/documentation/docs/30-advanced/40-service-workers.md
@@ -4,9 +4,9 @@ title: Service workers
 
 Service workers act as proxy servers that handle network requests inside your app. This makes it possible to make your app work offline, but even if you don't need offline support (or can't realistically implement it because of the type of app you're building), it's often worth using service workers to speed up navigation by precaching your built JS and CSS.
 
-In SvelteKit, if you have a `src/service-worker.js` file (or `src/service-worker.ts`, `src/service-worker/index.js`, etc) it will be bundled and automatically registered. You can change the [location of your service worker](/docs/configuration#files) if you need to.
+In SvelteKit, if you have a `src/service-worker.js` file (or `src/service-worker.ts`, `src/service-worker/index.js`, etc) it will be bundled and automatically registered. You can change the [location of your service worker](configuration#files) if you need to.
 
-You can [disable automatic registration](/docs/configuration#serviceworker) if you need to register the service worker with your own logic or use another solution. The default registration looks something like this:
+You can [disable automatic registration](configuration#serviceworker) if you need to register the service worker with your own logic or use another solution. The default registration looks something like this:
 
 ```js
 if ('serviceWorker' in navigator) {
@@ -18,7 +18,7 @@ if ('serviceWorker' in navigator) {
 
 ## Inside the service worker
 
-Inside the service worker you have access to the [`$service-worker` module](/docs/modules#$service-worker), which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string which you can use for creating a unique cache name. If your Vite config specifies `define` (used for global variable replacements), this will be applied to service workers as well as your server/client builds.
+Inside the service worker you have access to the [`$service-worker` module](modules#$service-worker), which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string which you can use for creating a unique cache name. If your Vite config specifies `define` (used for global variable replacements), this will be applied to service workers as well as your server/client builds.
 
 The following example caches the built app and any files in `static` eagerly, and caches all other requests as they happen. This would make each page work offline once visited.
 
diff --git a/documentation/docs/30-advanced/50-server-only-modules.md b/documentation/docs/30-advanced/50-server-only-modules.md
index e6c424003..d3141fe95 100644
--- a/documentation/docs/30-advanced/50-server-only-modules.md
+++ b/documentation/docs/30-advanced/50-server-only-modules.md
@@ -6,7 +6,7 @@ Like a good friend, SvelteKit keeps your secrets. When writing your backend and
 
 ## Private environment variables
 
-The `$env/static/private` and `$env/dynamic/private` modules, which are covered in the [modules](/docs/modules) section, can only be imported into modules that only run on the server, such as [`hooks.server.js`](/docs/hooks#server-hooks) or [`+page.server.js`](/docs/routing#page-page-server-js).
+The `$env/static/private` and `$env/dynamic/private` modules, which are covered in the [modules](modules) section, can only be imported into modules that only run on the server, such as [`hooks.server.js`](hooks#server-hooks) or [`+page.server.js`](routing#page-page-server-js).
 
 ## Your modules
 
diff --git a/documentation/docs/30-advanced/70-packaging.md b/documentation/docs/30-advanced/70-packaging.md
index f39f53446..38d17a9c3 100644
--- a/documentation/docs/30-advanced/70-packaging.md
+++ b/documentation/docs/30-advanced/70-packaging.md
@@ -6,17 +6,17 @@ title: Packaging
 
 You can use SvelteKit to build apps as well as component libraries, using the `@sveltejs/package` package (`npm create svelte` has an option to set this up for you).
 
-When you're creating an app, the contents of `src/routes` is the public-facing stuff; [`src/lib`](/docs/modules#$lib) contains your app's internal library.
+When you're creating an app, the contents of `src/routes` is the public-facing stuff; [`src/lib`](modules#$lib) contains your app's internal library.
 
 A component library has the exact same structure as a SvelteKit app, except that `src/lib` is the public-facing bit. `src/routes` might be a documentation or demo site that accompanies the library, or it might just be a sandbox you use during development.
 
-Running the `svelte-package` command from `@sveltejs/package` will take the contents of `src/lib` and generate a `package` directory (which can be [configured](/docs/configuration)) containing the following:
+Running the `svelte-package` command from `@sveltejs/package` will take the contents of `src/lib` and generate a `package` directory (which can be [configured](configuration)) containing the following:
 
-- All the files in `src/lib`, unless you [configure](/docs/configuration) custom `include`/`exclude` options. Svelte components will be preprocessed, TypeScript files will be transpiled to JavaScript.
-- Type definitions (`d.ts` files) which are generated for Svelte, JavaScript and TypeScript files. You need to install `typescript >= 4.0.0` for this. Type definitions are placed next to their implementation, hand-written `d.ts` files are copied over as is. You can [disable generation](/docs/configuration), but we strongly recommend against it — people using your library might use TypeScript, for which they require these type definition files.
+- All the files in `src/lib`, unless you [configure](configuration) custom `include`/`exclude` options. Svelte components will be preprocessed, TypeScript files will be transpiled to JavaScript.
+- Type definitions (`d.ts` files) which are generated for Svelte, JavaScript and TypeScript files. You need to install `typescript >= 4.0.0` for this. Type definitions are placed next to their implementation, hand-written `d.ts` files are copied over as is. You can [disable generation](configuration), but we strongly recommend against it — people using your library might use TypeScript, for which they require these type definition files.
 - A `package.json` copied from the project root with all fields except `"scripts"`, `"publishConfig.directory"` and `"publishConfig.linkDirectory"`. The `"dependencies"` field is included, which means you should add packages that you only need for your documentation or demo site to `"devDependencies"`. A `"type": "module"` and an `"exports"` field will be added if it's not defined in the original file.
 
-The `"exports"` field contains the package's entry points. By default, all files in `src/lib` will be treated as an entry point unless they start with (or live in a directory that starts with) an underscore, but you can [configure](/docs/configuration) this behaviour. If you have a `src/lib/index.js` or `src/lib/index.svelte` file, it will be treated as the package root.
+The `"exports"` field contains the package's entry points. By default, all files in `src/lib` will be treated as an entry point unless they start with (or live in a directory that starts with) an underscore, but you can [configure](configuration) this behaviour. If you have a `src/lib/index.js` or `src/lib/index.svelte` file, it will be treated as the package root.
 
 For example, if you had a `src/lib/Foo.svelte` component and a `src/lib/index.js` module that re-exported it, a consumer of your library could do either of the following:
 
@@ -38,7 +38,7 @@ declare module 'your-library/Foo.svelte';
 import Foo from 'your-library/Foo.svelte';
 ```
 
-> You should avoid using [SvelteKit-specific modules](/docs/modules) like `$app` in your packages unless you intend for them to only be consumable by other SvelteKit projects. E.g. rather than using `import { browser } from '$app/environment'` you could use [`import.meta.env.SSR`](https://vitejs.dev/guide/env-and-mode.html#env-variables) to make the library available to all Vite-based projects or better yet use [Node conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to make it work for all bundlers. You may also wish to pass in things like the current URL or a navigation action as a prop rather than relying directly on `$app/stores`, `$app/navigation`, etc. Writing your app in this more generic fashion will also make it easier to setup tools for testing, UI demos and so on.
+> You should avoid using [SvelteKit-specific modules](modules) like `$app` in your packages unless you intend for them to only be consumable by other SvelteKit projects. E.g. rather than using `import { browser } from '$app/environment'` you could use [`import.meta.env.SSR`](https://vitejs.dev/guide/env-and-mode.html#env-variables) to make the library available to all Vite-based projects or better yet use [Node conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to make it work for all bundlers. You may also wish to pass in things like the current URL or a navigation action as a prop rather than relying directly on `$app/stores`, `$app/navigation`, etc. Writing your app in this more generic fashion will also make it easier to setup tools for testing, UI demos and so on.
 
 ## Options
 
@@ -54,7 +54,7 @@ To publish the generated package:
 npm publish ./package
 ```
 
-The `./package` above is referring to the directory name generated, change accordingly if you configure a custom [`package.dir`](/docs/configuration).
+The `./package` above is referring to the directory name generated, change accordingly if you configure a custom [`package.dir`](configuration).
 
 ## Caveats
 
diff --git a/documentation/docs/40-best-practices/10-accessibility.md b/documentation/docs/40-best-practices/10-accessibility.md
index 5a85e00e0..2c45fa3f6 100644
--- a/documentation/docs/40-best-practices/10-accessibility.md
+++ b/documentation/docs/40-best-practices/10-accessibility.md
@@ -4,7 +4,7 @@ title: Accessibility
 
 SvelteKit strives to provide an accessible platform for your app by default. Svelte's [compile-time accessibility checks](https://svelte.dev/docs#accessibility-warnings) will also apply to any SvelteKit application you build.
 
-Here's how SvelteKit's built-in accessibility features work and what you need to do to help these features to work as well as possible. Keep in mind that while SvelteKit provides an accessible foundation, you are still responsible for making sure your application code is accessible. If you're new to accessibility, see the ["further reading"](/docs/accessibility#further-reading) section of this guide for additional resources.
+Here's how SvelteKit's built-in accessibility features work and what you need to do to help these features to work as well as possible. Keep in mind that while SvelteKit provides an accessible foundation, you are still responsible for making sure your application code is accessible. If you're new to accessibility, see the ["further reading"](accessibility#further-reading) section of this guide for additional resources.
 
 We recognize that accessibility can be hard to get right. If you want to suggest improvements to how SvelteKit handles accessibility, please [open a GitHub issue](https://github.com/sveltejs/kit/issues).
 
@@ -12,7 +12,7 @@ We recognize that accessibility can be hard to get right. If you want to suggest
 
 In traditional server-rendered applications, every navigation (e.g. clicking on an `<a>` tag) triggers a full page reload. When this happens, screen readers and other assistive technology will read out the new page's title so that users understand that the page has changed.
 
-Since navigation between pages in SvelteKit happens without reloading the page (known as [client-side routing](/docs/glossary#routing)), SvelteKit injects a [live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) onto the page that will read out the new page name after each navigation. This determines the page name to announce by inspecting the `<title>` element.
+Since navigation between pages in SvelteKit happens without reloading the page (known as [client-side routing](glossary#routing)), SvelteKit injects a [live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) onto the page that will read out the new page name after each navigation. This determines the page name to announce by inspecting the `<title>` element.
 
 Because of this behavior, every page in your app should have a unique, descriptive title. In SvelteKit, you can do this by placing a `<svelte:head>` element on each page:
 
@@ -23,7 +23,7 @@ Because of this behavior, every page in your app should have a unique, descripti
 </svelte:head>
 ```
 
-This will allow screen readers and other assistive technology to identify the new page after a navigation occurs. Providing a descriptive title is also important for [SEO](/docs/seo#manual-setup-title-and-meta).
+This will allow screen readers and other assistive technology to identify the new page after a navigation occurs. Providing a descriptive title is also important for [SEO](seo#manual-setup-title-and-meta).
 
 ## Focus management
 
@@ -45,7 +45,7 @@ afterNavigate(() => {
 });
 ```
 
-You can also programmatically navigate to a different page using the [`goto`](/docs/modules#$app-navigation-goto) function. By default, this will have the same client-side routing behavior as clicking on a link. However, `goto` also accepts a `keepFocus` option that will preserve the currently-focused element instead of resetting focus. If you enable this option, make sure the currently-focused element still exists on the page after navigation. If the element no longer exists, the user's focus will be lost, making for a confusing experience for assistive technology users.
+You can also programmatically navigate to a different page using the [`goto`](modules#$app-navigation-goto) function. By default, this will have the same client-side routing behavior as clicking on a link. However, `goto` also accepts a `keepFocus` option that will preserve the currently-focused element instead of resetting focus. If you enable this option, make sure the currently-focused element still exists on the page after navigation. If the element no longer exists, the user's focus will be lost, making for a confusing experience for assistive technology users.
 
 ## The "lang" attribute
 
@@ -56,7 +56,7 @@ By default, SvelteKit's page template sets the default language of the document
 <html lang="de">
 ```
 
-If your content is available in multiple languages, you should set the `lang` attribute based on the language of the current page. You can do this with SvelteKit's [handle hook](/docs/hooks#server-hooks-handle):
+If your content is available in multiple languages, you should set the `lang` attribute based on the language of the current page. You can do this with SvelteKit's [handle hook](hooks#server-hooks-handle):
 
 ```html
 /// file: src/app.html
diff --git a/documentation/docs/40-best-practices/20-seo.md b/documentation/docs/40-best-practices/20-seo.md
index 80f40d881..2abe6bbd1 100644
--- a/documentation/docs/40-best-practices/20-seo.md
+++ b/documentation/docs/40-best-practices/20-seo.md
@@ -8,7 +8,7 @@ The most important aspect of SEO is to create high-quality content that is widel
 
 ### SSR
 
-While search engines have got better in recent years at indexing content that was rendered with client-side JavaScript, server-side rendered content is indexed more frequently and reliably. SvelteKit employs SSR by default, and while you can disable it in [`handle`](/docs/hooks#server-hooks-handle), you should leave it on unless you have a good reason not to.
+While search engines have got better in recent years at indexing content that was rendered with client-side JavaScript, server-side rendered content is indexed more frequently and reliably. SvelteKit employs SSR by default, and while you can disable it in [`handle`](hooks#server-hooks-handle), you should leave it on unless you have a good reason not to.
 
 > SvelteKit's rendering is highly configurable and you can implement [dynamic rendering](https://developers.google.com/search/docs/advanced/javascript/dynamic-rendering) if necessary. It's not generally recommended, since SSR has other benefits beyond SEO.
 
@@ -18,7 +18,7 @@ Signals such as [Core Web Vitals](https://web.dev/vitals/#core-web-vitals) impac
 
 ### Normalized URLs
 
-SvelteKit redirects pathnames with trailing slashes to ones without (or vice versa depending on your [configuration](/docs/page-options#trailingslash)), as duplicate URLs are bad for SEO.
+SvelteKit redirects pathnames with trailing slashes to ones without (or vice versa depending on your [configuration](page-options#trailingslash)), as duplicate URLs are bad for SEO.
 
 ## Manual setup
 
@@ -26,7 +26,7 @@ SvelteKit redirects pathnames with trailing slashes to ones without (or vice ver
 
 Every page should have well-written and unique `<title>` and `<meta name="description">` elements inside a [`<svelte:head>`](https://svelte.dev/docs#template-syntax-svelte-head). Guidance on how to write descriptive titles and descriptions, along with other suggestions on making content understandable by search engines, can be found on Google's [Lighthouse SEO audits](https://web.dev/lighthouse-seo/) documentation.
 
-> A common pattern is to return SEO-related `data` from page [`load`](/docs/load) functions, then use it (as [`$page.data`](/docs/modules#$app-stores)) in a `<svelte:head>` in your root [layout](/docs/routing#layout).
+> A common pattern is to return SEO-related `data` from page [`load`](load) functions, then use it (as [`$page.data`](modules#$app-stores)) in a `<svelte:head>` in your root [layout](routing#layout).
 
 ### Structured data
 
@@ -83,7 +83,7 @@ export async function GET() {
 
 ### AMP
 
-An unfortunate reality of modern web development is that it is sometimes necessary to create an [Accelerated Mobile Pages (AMP)](https://amp.dev/) version of your site. In SvelteKit this can be done by setting the [`inlineStyleThreshold`](/docs/configuration#inlinestylethreshold) option...
+An unfortunate reality of modern web development is that it is sometimes necessary to create an [Accelerated Mobile Pages (AMP)](https://amp.dev/) version of your site. In SvelteKit this can be done by setting the [`inlineStyleThreshold`](configuration#inlinestylethreshold) option...
 
 ```js
 /// file: svelte.config.js
diff --git a/documentation/docs/50-reference/40-types.md b/documentation/docs/50-reference/40-types.md
index 90a654347..e5eb27e89 100644
--- a/documentation/docs/50-reference/40-types.md
+++ b/documentation/docs/50-reference/40-types.md
@@ -96,7 +96,7 @@ export async function load({ params, fetch }) {
 }
 ```
 
-> For this to work, your own `tsconfig.json` or `jsconfig.json` should extend from the generated `.svelte-kit/tsconfig.json` (where `.svelte-kit` is your [`outDir`](/docs/configuration#outdir)):
+> For this to work, your own `tsconfig.json` or `jsconfig.json` should extend from the generated `.svelte-kit/tsconfig.json` (where `.svelte-kit` is your [`outDir`](configuration#outdir)):
 >
 >     { "extends": "./.svelte-kit/tsconfig.json" }
 
diff --git a/documentation/docs/60-appendix/10-migrating.md b/documentation/docs/60-appendix/10-migrating.md
index 2e04f115c..a83e0dc63 100644
--- a/documentation/docs/60-appendix/10-migrating.md
+++ b/documentation/docs/60-appendix/10-migrating.md
@@ -5,7 +5,7 @@ rank: 1
 
 SvelteKit is the successor to Sapper and shares many elements of its design.
 
-If you have an existing Sapper app that you plan to migrate to SvelteKit, there are a number of changes you will need to make. You may find it helpful to view [some examples](/docs/additional-resources#examples) while migrating.
+If you have an existing Sapper app that you plan to migrate to SvelteKit, there are a number of changes you will need to make. You may find it helpful to view [some examples](additional-resources#examples) while migrating.
 
 ## package.json
 
@@ -20,14 +20,14 @@ Remove `polka` or `express`, if you're using one of those, and any middleware su
 
 ### devDependencies
 
-Remove `sapper` from your `devDependencies` and replace it with `@sveltejs/kit` and whichever [adapter](/docs/adapters) you plan to use (see [next section](/docs/migrating#project-files-configuration)).
+Remove `sapper` from your `devDependencies` and replace it with `@sveltejs/kit` and whichever [adapter](adapters) you plan to use (see [next section](migrating#project-files-configuration)).
 
 ### scripts
 
 Any scripts that reference `sapper` should be updated:
 
-- `sapper build` should become `vite build` using the Node [adapter](/docs/adapters)
-- `sapper export` should become `vite build` using the static [adapter](/docs/adapters)
+- `sapper build` should become `vite build` using the Node [adapter](adapters)
+- `sapper export` should become `vite build` using the static [adapter](adapters)
 - `sapper dev` should become `vite dev`
 - `node __sapper__/build` should become `node build`
 
@@ -37,11 +37,11 @@ The bulk of your app, in `src/routes`, can be left where it is, but several proj
 
 ### Configuration
 
-Your `webpack.config.js` or `rollup.config.js` should be replaced with a `svelte.config.js`, as documented [here](/docs/configuration). Svelte preprocessor options should be moved to `config.preprocess`.
+Your `webpack.config.js` or `rollup.config.js` should be replaced with a `svelte.config.js`, as documented [here](configuration). Svelte preprocessor options should be moved to `config.preprocess`.
 
-You will need to add an [adapter](/docs/adapters). `sapper build` is roughly equivalent to [adapter-node](https://github.com/sveltejs/kit/tree/master/packages/adapter-node) while `sapper export` is roughly equivalent to [adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static), though you might prefer to use an adapter designed for the platform you're deploying to.
+You will need to add an [adapter](adapters). `sapper build` is roughly equivalent to [adapter-node](https://github.com/sveltejs/kit/tree/master/packages/adapter-node) while `sapper export` is roughly equivalent to [adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static), though you might prefer to use an adapter designed for the platform you're deploying to.
 
-If you were using plugins for filetypes that are not automatically handled by [Vite](https://vitejs.dev), you will need to find Vite equivalents and add them to the [Vite config](/docs/project-structure#project-files-vite-config-js).
+If you were using plugins for filetypes that are not automatically handled by [Vite](https://vitejs.dev), you will need to find Vite equivalents and add them to the [Vite config](project-structure#project-files-vite-config-js).
 
 ### src/client.js
 
@@ -53,7 +53,7 @@ When using `adapter-node` the equivalent is a [custom server](https://github.com
 
 ### src/service-worker.js
 
-Most imports from `@sapper/service-worker` have equivalents in [`$service-worker`](/docs/modules#$service-worker):
+Most imports from `@sapper/service-worker` have equivalents in [`$service-worker`](modules#$service-worker):
 
 - `files` is unchanged
 - `routes` has been removed
@@ -68,36 +68,36 @@ Remove `%sapper.base%`, `%sapper.scripts%` and `%sapper.styles%`. Replace `%sapp
 
 ### src/node_modules
 
-A common pattern in Sapper apps is to put your internal library in a directory inside `src/node_modules`. This doesn't work with Vite, so we use [`src/lib`](/docs/modules#$lib) instead.
+A common pattern in Sapper apps is to put your internal library in a directory inside `src/node_modules`. This doesn't work with Vite, so we use [`src/lib`](modules#$lib) instead.
 
 ## Pages and layouts
 
 ### Renamed files
 
-Routes now are made up of the folder name exclusively to remove ambiguity, the folder names leading up to a `+page.svelte` correspond to the route. See [the routing docs](/docs/routing) for an overview. The following shows a old/new comparison:
+Routes now are made up of the folder name exclusively to remove ambiguity, the folder names leading up to a `+page.svelte` correspond to the route. See [the routing docs](routing) for an overview. The following shows a old/new comparison:
 
 | Old                       | New                       |
 | ------------------------- | ------------------------- |
 | routes/about/index.svelte | routes/about/+page.svelte |
 | routes/about.svelte       | routes/about/+page.svelte |
 
-Your custom error page component should be renamed from `_error.svelte` to `+error.svelte`. Any `_layout.svelte` files should likewise be renamed `+layout.svelte`. [Any other files are ignored](/docs/routing#other-files).
+Your custom error page component should be renamed from `_error.svelte` to `+error.svelte`. Any `_layout.svelte` files should likewise be renamed `+layout.svelte`. [Any other files are ignored](routing#other-files).
 
 ### Imports
 
-The `goto`, `prefetch` and `prefetchRoutes` imports from `@sapper/app` should be replaced with `goto`, `preloadData` and `preloadCode` imports respectively from [`$app/navigation`](/docs/modules#$app-navigation).
+The `goto`, `prefetch` and `prefetchRoutes` imports from `@sapper/app` should be replaced with `goto`, `preloadData` and `preloadCode` imports respectively from [`$app/navigation`](modules#$app-navigation).
 
-The `stores` import from `@sapper/app` should be replaced — see the [Stores](/docs/migrating#pages-and-layouts-stores) section below.
+The `stores` import from `@sapper/app` should be replaced — see the [Stores](migrating#pages-and-layouts-stores) section below.
 
-Any files you previously imported from directories in `src/node_modules` will need to be replaced with [`$lib`](/docs/modules#$lib) imports.
+Any files you previously imported from directories in `src/node_modules` will need to be replaced with [`$lib`](modules#$lib) imports.
 
 ### Preload
 
 As before, pages and layouts can export a function that allows data to be loaded before rendering takes place.
 
-This function has been renamed from `preload` to [`load`](/docs/load), it now lives in a `+page.js` (or `+layout.js`) next to its `+page.svelte` (or `+layout.svelte`), and its API has changed. Instead of two arguments — `page` and `session` — there is a single `event` argument.
+This function has been renamed from `preload` to [`load`](load), it now lives in a `+page.js` (or `+layout.js`) next to its `+page.svelte` (or `+layout.svelte`), and its API has changed. Instead of two arguments — `page` and `session` — there is a single `event` argument.
 
-There is no more `this` object, and consequently no `this.fetch`, `this.error` or `this.redirect`. Instead, you can get [`fetch`](/docs/load#making-fetch-requests) from the input methods, and both [`error`](/docs/load#errors) and [`redirect`](/docs/load#redirects) are now thrown.
+There is no more `this` object, and consequently no `this.fetch`, `this.error` or `this.redirect`. Instead, you can get [`fetch`](load#making-fetch-requests) from the input methods, and both [`error`](load#errors) and [`redirect`](load#redirects) are now thrown.
 
 ### Stores
 
@@ -115,11 +115,11 @@ const { preloading, page, session } = stores();
 
 The `page` store still exists; `preloading` has been replaced with a `navigating` store that contains `from` and `to` properties. `page` now has `url` and `params` properties, but no `path` or `query`.
 
-You access them differently in SvelteKit. `stores` is now `getStores`, but in most cases it is unnecessary since you can import `navigating`, and `page` directly from [`$app/stores`](/docs/modules#$app-stores).
+You access them differently in SvelteKit. `stores` is now `getStores`, but in most cases it is unnecessary since you can import `navigating`, and `page` directly from [`$app/stores`](modules#$app-stores).
 
 ### Routing
 
-Regex routes are no longer supported. Instead, use [advanced route matching](/docs/advanced-routing#matching).
+Regex routes are no longer supported. Instead, use [advanced route matching](advanced-routing#matching).
 
 ### Segments
 
@@ -138,7 +138,7 @@ This caused problems and is no longer the case in SvelteKit. Instead, relative U
 
 ## Endpoints
 
-In Sapper, [server routes](/docs/routing#server) received the `req` and `res` objects exposed by Node's `http` module (or the augmented versions provided by frameworks like Polka and Express).
+In Sapper, [server routes](routing#server) received the `req` and `res` objects exposed by Node's `http` module (or the augmented versions provided by frameworks like Polka and Express).
 
 SvelteKit is designed to be agnostic as to where the app is running — it could be running on a Node server, but could equally be running on a serverless platform or in a Cloudflare Worker. For that reason, you no longer interact directly with `req` and `res`. Your endpoints will need to be updated to match the new signature.
 
@@ -150,7 +150,7 @@ See [the FAQ](/faq#integrations) for detailed information about integrations.
 
 ### HTML minifier
 
-Sapper includes `html-minifier` by default. SvelteKit does not include this, but you can add it as a prod dependency and then use it through a [hook](/docs/hooks#server-hooks-handle):
+Sapper includes `html-minifier` by default. SvelteKit does not include this, but you can add it as a prod dependency and then use it through a [hook](hooks#server-hooks-handle):
 
 ```js
 // @filename: ambient.d.ts
diff --git a/documentation/docs/60-appendix/30-glossary.md b/documentation/docs/60-appendix/30-glossary.md
index 42ceadeed..9b70b8dbc 100644
--- a/documentation/docs/60-appendix/30-glossary.md
+++ b/documentation/docs/60-appendix/30-glossary.md
@@ -8,41 +8,41 @@ The core of SvelteKit provides a highly configurable rendering engine. This sect
 
 Client-side rendering (CSR) is the generation of the page contents in the web browser using JavaScript.
 
-In SvelteKit, client-side rendering will be used by default, but you can turn off JavaScript with [the `csr = false` page option](/docs/page-options#csr).
+In SvelteKit, client-side rendering will be used by default, but you can turn off JavaScript with [the `csr = false` page option](page-options#csr).
 
 ## Hydration
 
 Svelte components store some state and update the DOM when the state is updated. When fetching data during SSR, by default SvelteKit will store this data and transmit it to the client along with the server-rendered HTML. The components can then be initialized on the client with that data without having to call the same API endpoints again. Svelte will then check that the DOM is in the expected state and attach event listeners in a process called hydration. Once the components are fully hydrated, they can react to changes to their properties just like any newly created Svelte component.
 
-In SvelteKit, pages will be hydrated by default, but you can turn off JavaScript with [the `csr = false` page option](/docs/page-options#csr).
+In SvelteKit, pages will be hydrated by default, but you can turn off JavaScript with [the `csr = false` page option](page-options#csr).
 
 ## Prerendering
 
 Prerendering means computing the contents of a page at build time and saving the HTML for display. This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process is more expensive and prerendered content can only be updated by building and deploying a new version of the application.
 
-Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain [actions](/docs/form-actions). Note that you can still prerender content that is loaded based on the page's parameters as long as all users will be seeing the same prerendered content.
+Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain [actions](form-actions). Note that you can still prerender content that is loaded based on the page's parameters as long as all users will be seeing the same prerendered content.
 
 Pre-rendered pages are not limited to static content. You can build personalized pages if user-specific data is fetched and rendered client-side. This is subject to the caveat that you will experience the downsides of not doing SSR for that content as discussed above.
 
-In SvelteKit, you can control prerendering with [the `prerender` page option](/docs/page-options#prerender) and [`prerender` config](/docs/configuration#prerender) in `svelte.config.js`.
+In SvelteKit, you can control prerendering with [the `prerender` page option](page-options#prerender) and [`prerender` config](configuration#prerender) in `svelte.config.js`.
 
 ## Routing
 
 By default, when you navigate to a new page (by clicking on a link or using the browser's forward or back buttons), SvelteKit will intercept the attempted navigation and handle it instead of allowing the browser to send a request to the server for the destination page. SvelteKit will then update the displayed contents on the client by rendering the component for the new page, which in turn can make calls to the necessary API endpoints. This process of updating the page on the client in response to attempted navigation is called client-side routing.
 
-In SvelteKit, client-side routing will be used by default, but you can skip it with [`data-sveltekit-reload`](/docs/link-options#data-sveltekit-reload).
+In SvelteKit, client-side routing will be used by default, but you can skip it with [`data-sveltekit-reload`](link-options#data-sveltekit-reload).
 
 ## SPA
 
 A single-page app (SPA) is an application in which all requests to the server load a single HTML file which then does client-side rendering of the requested contents based on the requested URL. All navigation is handled on the client-side in a process called client-side routing with per-page contents being updated and common layout elements remaining largely unchanged. SPAs do not provide SSR, which has the shortcoming described above. However, some applications are not greatly impacted by these shortcomings such as a complex business application behind a login where SEO would not be important and it is known that users will be accessing the application from a consistent computing environment.
 
-In SvelteKit, you can [build a SPA with `adapter-static`](/docs/adapter-static#spa-mode).
+In SvelteKit, you can [build a SPA with `adapter-static`](adapter-static#spa-mode).
 
 ## SSG
 
 Static Site Generation (SSG) is a term that refers to a site where every page is prerendered. SvelteKit was not built to do only static site generation like some tools and so may not scale as well to efficiently render a very large number of pages as tools built specifically for that purpose. However, in contrast to most purpose-built SSGs, SvelteKit does nicely allow for mixing and matching different rendering types on different pages. One benefit of fully prerendering a site is that you do not need to maintain or pay for servers to perform SSR. Once generated, the site can be served from CDNs, leading to great "time to first byte" performance. This delivery model is often referred to as JAMstack.
 
-In SvelteKit, you can do static site generation by using [`adapter-static`](/docs/adapter-static) or by configuring every page to be prerendered using [the `prerender` page option](/docs/page-options#prerender) or [`prerender` config](/docs/configuration#prerender) in `svelte.config.js`.
+In SvelteKit, you can do static site generation by using [`adapter-static`](adapter-static) or by configuring every page to be prerendered using [the `prerender` page option](page-options#prerender) or [`prerender` config](configuration#prerender) in `svelte.config.js`.
 
 ## SSR
 
diff --git a/documentation/faq/60-read-package-json.md b/documentation/faq/60-read-package-json.md
index 25a591993..f99dca9d0 100644
--- a/documentation/faq/60-read-package-json.md
+++ b/documentation/faq/60-read-package-json.md
@@ -2,7 +2,7 @@
 title: How do I include details from package.json in my application?
 ---
 
-You cannot directly require JSON files, since SvelteKit expects [`svelte.config.js`](/docs/configuration) to be an ES module. If you'd like to include your application's version number or other information from `package.json` in your application, you can load JSON like so:
+You cannot directly require JSON files, since SvelteKit expects [`svelte.config.js`](docs/configuration) to be an ES module. If you'd like to include your application's version number or other information from `package.json` in your application, you can load JSON like so:
 
 ```js
 /// file: svelte.config.js
diff --git a/documentation/faq/70-packages.md b/documentation/faq/70-packages.md
index 1eebf3f4a..5a8d1ebe3 100644
--- a/documentation/faq/70-packages.md
+++ b/documentation/faq/70-packages.md
@@ -9,7 +9,7 @@ Here are a few things to keep in mind when checking if a library is packaged cor
 - `exports` takes precedence over the other entry point fields such as `main` and `module`. Adding an `exports` field may not be backwards-compatible as it prevents deep imports.
 - ESM files should end with `.mjs` unless `"type": "module"` is set in which any case CommonJS files should end with `.cjs`.
 - `main` should be defined if `exports` is not. It should be either a CommonJS or ESM file and adhere to the previous bullet. If a `module` field is defined, it should refer to an ESM file.
-- Svelte components should be distributed as uncompiled `.svelte` files with any JS in the package written as ESM only. Custom script and style languages, like TypeScript and SCSS, should be preprocessed as vanilla JS and CSS respectively. We recommend using [`svelte-package`](/docs/packaging) for packaging Svelte libraries, which will do this for you.
+- Svelte components should be distributed as uncompiled `.svelte` files with any JS in the package written as ESM only. Custom script and style languages, like TypeScript and SCSS, should be preprocessed as vanilla JS and CSS respectively. We recommend using [`svelte-package`](docs/packaging) for packaging Svelte libraries, which will do this for you.
 
 Libraries work best in the browser with Vite when they distribute an ESM version, especially if they are dependencies of a Svelte component library. You may wish to suggest to library authors that they provide an ESM version. However, CommonJS (CJS) dependencies should work as well since, by default, [`vite-plugin-svelte` will ask Vite to pre-bundle them](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#what-is-going-on-with-vite-and-pre-bundling-dependencies) using `esbuild` to convert them to ESM.
 
diff --git a/documentation/faq/80-integrations.md b/documentation/faq/80-integrations.md
index 3fb04b932..32d5619d7 100644
--- a/documentation/faq/80-integrations.md
+++ b/documentation/faq/80-integrations.md
@@ -2,11 +2,11 @@
 title: How do I use X with SvelteKit?
 ---
 
-Make sure you've read the [documentation section on integrations](/docs/integrations). If you're still having trouble, solutions to common issues are listed below.
+Make sure you've read the [documentation section on integrations](docs/integrations). If you're still having trouble, solutions to common issues are listed below.
 
 ### How do I setup a database?
 
-Put the code to query your database in a [server route](/docs/routing#server) - don't query the database in .svelte files. You can create a `db.js` or similar that sets up a connection immediately and makes the client accessible throughout the app as a singleton. You can execute any one-time setup code in `hooks.js` and import your database helpers into any endpoint that needs them.
+Put the code to query your database in a [server route](docs/routing#server) - don't query the database in .svelte files. You can create a `db.js` or similar that sets up a connection immediately and makes the client accessible throughout the app as a singleton. You can execute any one-time setup code in `hooks.js` and import your database helpers into any endpoint that needs them.
 
 ### How do I use a client-side only library that depends on `document` or `window`?
 
@@ -75,7 +75,7 @@ onMount(() => {
 
 ### How do I use a different backend API server?
 
-You can use [`event.fetch`](/docs/load#making-fetch-requests) to request data from an external API server, but be aware that you would need to deal with [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), which will result in complications such as generally requiring requests to be preflighted resulting in higher latency. Requests to a separate subdomain may also increase latency due to an additional DNS lookup, TLS setup, etc. If you wish to use this method, you may find [`handleFetch`](/docs/hooks#server-hooks-handlefetch) helpful.
+You can use [`event.fetch`](docs/load#making-fetch-requests) to request data from an external API server, but be aware that you would need to deal with [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), which will result in complications such as generally requiring requests to be preflighted resulting in higher latency. Requests to a separate subdomain may also increase latency due to an additional DNS lookup, TLS setup, etc. If you wish to use this method, you may find [`handleFetch`](docs/hooks#server-hooks-handlefetch) helpful.
 
 Another approach is to set up a proxy to bypass CORS headaches. In production, you would rewrite a path like `/api` to the API server; for local development, use Vite's [`server.proxy`](https://vitejs.dev/config/server-options.html#server-proxy) option.
 
diff --git a/packages/adapter-netlify/CHANGELOG.md b/packages/adapter-netlify/CHANGELOG.md
index 75463fd13..a09d7d478 100644
--- a/packages/adapter-netlify/CHANGELOG.md
+++ b/packages/adapter-netlify/CHANGELOG.md
@@ -1,5 +1,14 @@
 # @sveltejs/adapter-netlify
 
+## 1.0.5
+
+### Patch Changes
+
+- chore: update link to docs for missing netlify.toml warning ([#8673](https://github.com/sveltejs/kit/pull/8673))
+
+- Updated dependencies [[`24d2efe4`](https://github.com/sveltejs/kit/commit/24d2efe4e5b641b9caacf21ba77a42f812b3b120)]:
+  - @sveltejs/kit@1.2.4
+
 ## 1.0.4
 
 ### Patch Changes
diff --git a/packages/adapter-netlify/package.json b/packages/adapter-netlify/package.json
index 98fc095a8..da3955d04 100644
--- a/packages/adapter-netlify/package.json
+++ b/packages/adapter-netlify/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/adapter-netlify",
-	"version": "1.0.4",
+	"version": "1.0.5",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md
index 3ed29909a..2b91378a3 100644
--- a/packages/kit/CHANGELOG.md
+++ b/packages/kit/CHANGELOG.md
@@ -1,5 +1,17 @@
 # @sveltejs/kit
 
+## 1.2.5
+
+### Patch Changes
+
+- fix: check for wrong return values from form actions ([#8553](https://github.com/sveltejs/kit/pull/8553))
+
+## 1.2.4
+
+### Patch Changes
+
+- chore: update undici to v5.16.0 ([#8668](https://github.com/sveltejs/kit/pull/8668))
+
 ## 1.2.3
 
 ### Patch Changes
diff --git a/packages/kit/package.json b/packages/kit/package.json
index 61d96bc9a..df60de14e 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/kit",
-	"version": "1.2.3",
+	"version": "1.2.5",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js
index a2ba0d881..a5bf770a0 100644
--- a/packages/kit/src/exports/vite/dev/index.js
+++ b/packages/kit/src/exports/vite/dev/index.js
@@ -364,10 +364,13 @@ export async function dev(vite, vite_config, svelte_config) {
 				/** @type {function} */ (middleware.handle).name === 'viteServeStaticMiddleware'
 		);
 
+		// Vite will give a 403 on URLs like /test, /static, and /package.json preventing us from
+		// serving routes with those names. See https://github.com/vitejs/vite/issues/7363
 		remove_static_middlewares(vite.middlewares);
 
 		vite.middlewares.use(async (req, res) => {
 			// Vite's base middleware strips out the base path. Restore it
+			const original_url = req.url;
 			req.url = req.originalUrl;
 			try {
 				const base = `${vite.config.server.https ? 'https' : 'http'}://${
@@ -375,13 +378,14 @@ export async function dev(vite, vite_config, svelte_config) {
 				}`;
 
 				const decoded = decodeURI(new URL(base + req.url).pathname);
-				const file = posixify(path.resolve(decoded.slice(1)));
+				const file = posixify(path.resolve(decoded.slice(svelte_config.kit.paths.base.length + 1)));
 				const is_file = fs.existsSync(file) && !fs.statSync(file).isDirectory();
 				const allowed =
 					!vite_config.server.fs.strict ||
 					vite_config.server.fs.allow.some((dir) => file.startsWith(dir));
 
 				if (is_file && allowed) {
+					req.url = original_url;
 					// @ts-expect-error
 					serve_static_middleware.handle(req, res);
 					return;
diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js
index afb3ee67a..abf2f79cf 100644
--- a/packages/kit/src/runtime/server/page/actions.js
+++ b/packages/kit/src/runtime/server/page/actions.js
@@ -24,9 +24,6 @@ export async function handle_action_json_request(event, options, server) {
 	const actions = server?.actions;
 
 	if (!actions) {
-		if (server) {
-			maybe_throw_migration_error(server);
-		}
 		// TODO should this be a different error altogether?
 		const no_actions_error = error(405, 'POST method not allowed. No actions exist for this page');
 		return action_json(
@@ -50,6 +47,10 @@ export async function handle_action_json_request(event, options, server) {
 	try {
 		const data = await call_action(event, actions);
 
+		if (__SVELTEKIT_DEV__) {
+			validate_action_return(data);
+		}
+
 		if (data instanceof ActionFailure) {
 			return action_json({
 				type: 'failure',
@@ -124,7 +125,6 @@ export async function handle_action_request(event, server) {
 	const actions = server.actions;
 
 	if (!actions) {
-		maybe_throw_migration_error(server);
 		// TODO should this be a different error altogether?
 		event.setHeaders({
 			// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
@@ -142,13 +142,22 @@ export async function handle_action_request(event, server) {
 	try {
 		const data = await call_action(event, actions);
 
+		if (__SVELTEKIT_DEV__) {
+			validate_action_return(data);
+		}
+
 		if (data instanceof ActionFailure) {
-			return { type: 'failure', status: data.status, data: data.data };
+			return {
+				type: 'failure',
+				status: data.status,
+				data: data.data
+			};
 		} else {
 			return {
 				type: 'success',
 				status: 200,
-				data: /** @type {Record<string, any> | undefined} */ (data)
+				// @ts-expect-error this will be removed upon serialization, so `undefined` is the same as omission
+				data
 			};
 		}
 	} catch (e) {
@@ -185,7 +194,7 @@ function check_named_default_separate(actions) {
  * @param {NonNullable<import('types').SSRNode['server']['actions']>} actions
  * @throws {Redirect | ActionFailure | HttpError | Error}
  */
-export async function call_action(event, actions) {
+async function call_action(event, actions) {
 	const url = new URL(event.request.url);
 
 	let name = 'default';
@@ -213,16 +222,16 @@ export async function call_action(event, actions) {
 	return action(event);
 }
 
-/**
- * @param {import('types').SSRNode['server']} server
- */
-function maybe_throw_migration_error(server) {
-	for (const method of ['POST', 'PUT', 'PATCH', 'DELETE']) {
-		if (/** @type {any} */ (server)[method]) {
-			throw new Error(
-				`${method} method no longer allowed in +page.server, use actions instead. See the PR for more info: https://github.com/sveltejs/kit/pull/6469`
-			);
-		}
+/** @param {any} data */
+function validate_action_return(data) {
+	if (data instanceof Redirect) {
+		throw new Error(`Cannot \`return redirect(...)\` — use \`throw redirect(...)\` instead`);
+	}
+
+	if (data instanceof HttpError) {
+		throw new Error(
+			`Cannot \`return error(...)\` — use \`throw error(...)\` or \`return fail(...)\` instead`
+		);
 	}
 }
 
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e52eda5fd..1c1c6a00c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -702,7 +702,7 @@ importers:
       typescript: ^4.9.4
       uvu: ^0.5.6
       vite: ^4.0.4
-      vite-imagetools: ^4.0.13
+      vite-imagetools: ^4.0.16
     dependencies:
       d3-geo: 3.0.1
       d3-geo-projection: 4.0.0
@@ -725,7 +725,7 @@ importers:
       typescript: 4.9.4
       uvu: 0.5.6
       vite: 4.0.4_@types+node@16.18.6
-      vite-imagetools: 4.0.13
+      vite-imagetools: 4.0.16
 
 packages:
 
@@ -2610,8 +2610,8 @@ packages:
     engines: {node: '>= 4'}
     dev: true
 
-  /imagetools-core/3.2.3:
-    resolution: {integrity: sha512-YbZhedg/zja34yV6iRDhfo4cmAYSwxaErkuzc/RpMMAELgszpDKf3MLH6VlsR+QkenPUEGkGAVpJAM2GbUls9Q==}
+  /imagetools-core/3.3.1:
+    resolution: {integrity: sha512-xllF2GDRg0SXCQQRxBAtE6N9dPAttc+ro+QDLnRmVSE5lH5clQxD2Al4XluirXj0T7lIH5VbetFmBLowW6ps+w==}
     engines: {node: '>=12.0.0'}
     dependencies:
       sharp: 0.31.3
@@ -4532,12 +4532,12 @@ packages:
       spdx-expression-parse: 3.0.1
     dev: true
 
-  /vite-imagetools/4.0.13:
-    resolution: {integrity: sha512-DeMAhDwvWATzBa5Qu9Fv6rtOuHZFONrv5Z5a95jd/oBDDCdyTKYVqxIurS5ox9A/sH8bhVF7r++Yww0DKpjKFQ==}
+  /vite-imagetools/4.0.16:
+    resolution: {integrity: sha512-kjTIcscDYEXLxTeCRVZVArygEOgFBoG6pno6H6wBpq6R07Lov/zRDG7UX/yw3DgMFzeVPWJW8YuItT7M0puSDw==}
     engines: {node: '>=12.0.0'}
     dependencies:
       '@rollup/pluginutils': 5.0.2
-      imagetools-core: 3.2.3
+      imagetools-core: 3.3.1
     transitivePeerDependencies:
       - rollup
     dev: true
diff --git a/sites/kit.svelte.dev/package.json b/sites/kit.svelte.dev/package.json
index 74011f10e..488e8d6d2 100644
--- a/sites/kit.svelte.dev/package.json
+++ b/sites/kit.svelte.dev/package.json
@@ -27,7 +27,7 @@
 		"typescript": "^4.9.4",
 		"uvu": "^0.5.6",
 		"vite": "^4.0.4",
-		"vite-imagetools": "^4.0.13"
+		"vite-imagetools": "^4.0.16"
 	},
 	"type": "module",
 	"dependencies": {
diff --git a/sites/kit.svelte.dev/src/routes/+layout.svelte b/sites/kit.svelte.dev/src/routes/+layout.svelte
index 441e2658e..beac48120 100644
--- a/sites/kit.svelte.dev/src/routes/+layout.svelte
+++ b/sites/kit.svelte.dev/src/routes/+layout.svelte
@@ -1,6 +1,7 @@
 <script>
 	import '@sveltejs/site-kit/styles/index.css';
 	import { browser } from '$app/environment';
+	import { base } from '$app/paths';
 	import { page, navigating } from '$app/stores';
 	import Icon from '@sveltejs/site-kit/components/Icon.svelte';
 	import Icons from '@sveltejs/site-kit/components/Icons.svelte';
@@ -32,10 +33,10 @@
 	</svelte:fragment>
 
 	<svelte:fragment slot="nav-right">
-		<NavItem selected={$page.url.pathname.startsWith('/docs') || undefined} href="/docs"
+		<NavItem selected={$page.url.pathname.startsWith(`${base}/docs`) || undefined} href="{base}/docs"
 			>Docs</NavItem
 		>
-		<NavItem selected={$page.url.pathname.startsWith('/faq') || undefined} href="/faq">FAQ</NavItem>
+		<NavItem selected={$page.url.pathname.startsWith(`${base}/faq`) || undefined} href="{base}/faq">FAQ</NavItem>
 
 		<li aria-hidden="true"><span class="separator" /></li>
 
diff --git a/sites/kit.svelte.dev/src/routes/docs/+layout.server.js b/sites/kit.svelte.dev/src/routes/docs/+layout.server.js
index 48ed44658..8e7653022 100644
--- a/sites/kit.svelte.dev/src/routes/docs/+layout.server.js
+++ b/sites/kit.svelte.dev/src/routes/docs/+layout.server.js
@@ -1,32 +1,33 @@
 import fs from 'fs';
+import { base } from '$app/paths';
 import { extract_frontmatter } from '$lib/docs/server/markdown';
 
 export const prerender = true;
 
-const base = '../../documentation/docs';
+const base_dir = '../../documentation/docs';
 const pattern = /^\d\d-/;
 
 /** @type {import('./$types').LayoutServerLoad} */
 export function load() {
 	const sections = fs
-		.readdirSync(base)
+		.readdirSync(base_dir)
 		.filter((subdir) => pattern.test(subdir))
 		.map((subdir) => {
-			const meta = JSON.parse(fs.readFileSync(`${base}/${subdir}/meta.json`, 'utf-8'));
+			const meta = JSON.parse(fs.readFileSync(`${base_dir}/${subdir}/meta.json`, 'utf-8'));
 			return {
 				title: meta.title,
 				pages: fs
-					.readdirSync(`${base}/${subdir}`)
+					.readdirSync(`${base_dir}/${subdir}`)
 					.filter((file) => pattern.test(file))
 					.map((file) => {
-						const markdown = fs.readFileSync(`${base}/${subdir}/${file}`, 'utf-8');
+						const markdown = fs.readFileSync(`${base_dir}/${subdir}/${file}`, 'utf-8');
 						const { metadata } = extract_frontmatter(markdown);
 
 						const slug = file.slice(3, -3);
 
 						return {
 							title: metadata.title,
-							path: `/docs/${slug}`
+							path: `${base}/docs/${slug}`
 						};
 					})
 			};
diff --git a/sites/kit.svelte.dev/src/routes/docs/+page.js b/sites/kit.svelte.dev/src/routes/docs/+page.js
index 5c6da2c13..272cd1903 100644
--- a/sites/kit.svelte.dev/src/routes/docs/+page.js
+++ b/sites/kit.svelte.dev/src/routes/docs/+page.js
@@ -1,6 +1,7 @@
 import { redirect } from '@sveltejs/kit';
+import { base } from '$app/paths';
 
 /** @type {import('./$types').Load} */
 export function load() {
-	throw redirect(307, '/docs/introduction');
+	throw redirect(307, `${base}/docs/introduction`);
 }
diff --git a/sites/kit.svelte.dev/src/routes/docs/[slug]/OnThisPage.svelte b/sites/kit.svelte.dev/src/routes/docs/[slug]/OnThisPage.svelte
index 32ba78efd..c8e183294 100644
--- a/sites/kit.svelte.dev/src/routes/docs/[slug]/OnThisPage.svelte
+++ b/sites/kit.svelte.dev/src/routes/docs/[slug]/OnThisPage.svelte
@@ -1,6 +1,7 @@
 <script>
 	import { onMount } from 'svelte';
 	import { afterNavigate } from '$app/navigation';
+	import { base } from '$app/paths';
 	import { page } from '$app/stores';
 
 	/** @type {import('./$types').PageData['page']} */
@@ -86,7 +87,7 @@
 	<h2>On this page</h2>
 	<nav>
 		<ul>
-			<li><a href="/docs/{details.slug}" class:active={hash === ''}>{details.title}</a></li>
+			<li><a href="{base}/docs/{details.slug}" class:active={hash === ''}>{details.title}</a></li>
 			{#each details.sections as { title, slug }}
 				<li><a href={`#${slug}`} class:active={`#${slug}` === hash}>{title}</a></li>
 			{/each}
diff --git a/sites/kit.svelte.dev/src/routes/home/Hero.svelte b/sites/kit.svelte.dev/src/routes/home/Hero.svelte
index 1b360b355..80426060c 100644
--- a/sites/kit.svelte.dev/src/routes/home/Hero.svelte
+++ b/sites/kit.svelte.dev/src/routes/home/Hero.svelte
@@ -1,4 +1,5 @@
 <script>
+	import { base } from '$app/paths';
 	import logotype from './svelte-kit-logotype.svg';
 	import background from './svelte-kit-machine.webp?w=1440;960&format=avif;webp;png&picture';
 </script>
@@ -8,7 +9,7 @@
 		<div class="hero-text">
 			<img alt="SvelteKit logotype" width="400" height="50" class="logotype" src={logotype} />
 			<div class="tagline">web development, streamlined</div>
-			<a class="cta" href="/docs/introduction">read the docs</a>
+			<a class="cta" href="{base}/docs/introduction">read the docs</a>
 		</div>
 
 		<picture class="hero-image">


Test patch:
diff --git a/packages/kit/test/apps/options/source/pages/test.txt b/packages/kit/test/apps/options/source/pages/test.txt
new file mode 100644
index 000000000..113924c6b
--- /dev/null
+++ b/packages/kit/test/apps/options/source/pages/test.txt
@@ -0,0 +1,1 @@
+hello there world
diff --git a/packages/kit/test/apps/options/test/test.js b/packages/kit/test/apps/options/test/test.js
index 8ddcca4f7..c79e42758 100644
--- a/packages/kit/test/apps/options/test/test.js
+++ b/packages/kit/test/apps/options/test/test.js
@@ -32,6 +32,16 @@ test.describe('base path', () => {
 		);
 	});
 
+	if (process.env.DEV) {
+		test('serves files in source directory', async ({ request, javaScriptEnabled }) => {
+			if (!javaScriptEnabled) return;
+
+			const response = await request.get('/path-base/source/pages/test.txt');
+			expect(response.ok()).toBe(true);
+			expect(await response.text()).toBe('hello there world\n');
+		});
+	}
+
 	test('sets_paths', async ({ page }) => {
 		await page.goto('/path-base/base/');
 		expect(await page.textContent('[data-source="base"]')).toBe('/path-base');
@@ -234,14 +244,14 @@ test.describe('trailingSlash', () => {
 	});
 });
 
-test.describe('serviceWorker', () => {
-	if (process.env.DEV) return;
-
-	test('does not register service worker if none created', async ({ page }) => {
-		await page.goto('/path-base/');
-		expect(await page.content()).not.toMatch('navigator.serviceWorker');
+if (!process.env.DEV) {
+	test.describe('serviceWorker', () => {
+		test('does not register service worker if none created', async ({ page }) => {
+			await page.goto('/path-base/');
+			expect(await page.content()).not.toMatch('navigator.serviceWorker');
+		});
 	});
-});
+}
 
 test.describe('Vite options', () => {
 	test('Respects --mode', async ({ page }) => {