diff --git a/documentation/docs/20-core-concepts/30-form-actions.md b/documentation/docs/20-core-concepts/30-form-actions.md index 8dc852b985c0..48bd968bf87e 100644 --- a/documentation/docs/20-core-concepts/30-form-actions.md +++ b/documentation/docs/20-core-concepts/30-form-actions.md @@ -469,6 +469,7 @@ Note that you need to `deserialize` the response before processing it further us If you have a `+server.js` alongside your `+page.server.js`, `fetch` requests will be routed there by default. To `POST` to an action in `+page.server.js` instead, use the custom `x-sveltekit-action` header: ```js +// @errors: 2532 2304 const response = await fetch(this.action, { method: 'POST', body: data, 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 ce0a5bccf95f..1ab9a5e814b0 100644 --- a/documentation/docs/25-build-and-deploy/40-adapter-node.md +++ b/documentation/docs/25-build-and-deploy/40-adapter-node.md @@ -13,11 +13,14 @@ Install with `npm i -D @sveltejs/adapter-node`, then add the adapter to your `sv /// file: svelte.config.js import adapter from '@sveltejs/adapter-node'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter() } }; + +export default config; ``` ## Deploying @@ -146,7 +149,8 @@ The adapter can be configured with various options: /// file: svelte.config.js import adapter from '@sveltejs/adapter-node'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // default options are shown @@ -156,6 +160,8 @@ export default { }) } }; + +export default config; ``` ### out 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 c1d4845af154..7c09daf155ae 100644 --- a/documentation/docs/25-build-and-deploy/50-adapter-static.md +++ b/documentation/docs/25-build-and-deploy/50-adapter-static.md @@ -11,11 +11,11 @@ This will prerender your entire site as a collection of static files. If you'd l Install with `npm i -D @sveltejs/adapter-static`, then add the adapter to your `svelte.config.js`: ```js -// @errors: 2307 /// file: svelte.config.js import adapter from '@sveltejs/adapter-static'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // default options are shown. On some platforms @@ -28,6 +28,8 @@ export default { }) } }; + +export default config; ``` ...and add the [`prerender`](page-options#prerender) option to your root layout: @@ -49,13 +51,17 @@ Some platforms have zero-config support (more to come in future): On these platforms, you should omit the adapter options so that `adapter-static` can provide the optimal configuration: ```js -// @errors: 2304 /// file: svelte.config.js -export default { +import adapter from '@sveltejs/adapter-static'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter(---{...}---) } }; + +export default config; ``` ## Options @@ -89,7 +95,7 @@ You'll also want to generate a fallback `404.html` page to replace the default 4 A config for GitHub Pages might look like the following: ```js -// @errors: 2307 2322 +// @errors: 2322 /// file: svelte.config.js import adapter from '@sveltejs/adapter-static'; diff --git a/documentation/docs/25-build-and-deploy/55-single-page-apps.md b/documentation/docs/25-build-and-deploy/55-single-page-apps.md index 9747c4288a51..8367f88fbef6 100644 --- a/documentation/docs/25-build-and-deploy/55-single-page-apps.md +++ b/documentation/docs/25-build-and-deploy/55-single-page-apps.md @@ -18,17 +18,19 @@ If you don't have any server-side logic (i.e. `+page.server.js`, `+layout.server Install with `npm i -D @sveltejs/adapter-static`, then add the adapter to your `svelte.config.js` with the following options: ```js -// @errors: 2307 /// file: svelte.config.js import adapter from '@sveltejs/adapter-static'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ fallback: '200.html' // may differ from host to host }) } }; + +export default config; ``` The `fallback` page is an HTML page created by SvelteKit from your page template (e.g. `app.html`) that loads your app and navigates to the correct route. For example [Surge](https://surge.sh/help/adding-a-200-page-for-client-side-routing), a static web host, lets you add a `200.html` file that will handle any requests that don't correspond to static assets or prerendered pages. 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 665214fb718b..58cbe799fad0 100644 --- a/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md +++ b/documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md @@ -20,7 +20,8 @@ Install with `npm i -D @sveltejs/adapter-cloudflare`, then add the adapter to yo /// file: svelte.config.js import adapter from '@sveltejs/adapter-cloudflare'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // See below for an explanation of these options @@ -38,6 +39,8 @@ export default { }) } }; + +export default config; ``` ## Options @@ -125,9 +128,25 @@ Functions contained in the [`/functions` directory](https://developers.cloudflar The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#parameters) object contains your project's [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform` property, along with [`context`](https://developers.cloudflare.com/workers/runtime-apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/cache/), and [`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), meaning that you can access it in hooks and endpoints: ```js -// @errors: 7031 +// @filename: ambient.d.ts +import { DurableObjectNamespace } from '@cloudflare/workers-types'; + +declare global { + namespace App { + interface Platform { + env: { + YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace; + }; + } + } +} +// @filename: +server.js +// ---cut--- +// @errors: 2355 2322 +/// file: +server.js +/** @type {import('./$types').RequestHandler} */ export async function POST({ request, platform }) { - const x = platform.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x'); + const x = platform?.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x'); } ``` @@ -142,7 +161,7 @@ To make these types available to your app, install [`@cloudflare/workers-types`] declare global { namespace App { interface Platform { -+++ env?: { ++++ env: { YOUR_KV_NAMESPACE: KVNamespace; YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace; };+++ @@ -193,15 +212,19 @@ Cloudflare no longer recommends using [Workers Sites](https://developers.cloudfl ### svelte.config.js ```js +// @errors: 2307 /// file: svelte.config.js ---import adapter from '@sveltejs/adapter-cloudflare-workers';--- +++import adapter from '@sveltejs/adapter-cloudflare';+++ -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter() } }; + +export default config; ``` ### wrangler.toml diff --git a/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md b/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md index 942f57fed034..c97349f40093 100644 --- a/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md +++ b/documentation/docs/25-build-and-deploy/70-adapter-cloudflare-workers.md @@ -15,13 +15,16 @@ Install with `npm i -D @sveltejs/adapter-cloudflare-workers`, then add the adapt /// file: svelte.config.js import adapter from '@sveltejs/adapter-cloudflare-workers'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // see below for options that can be set here }) } }; + +export default config; ``` ## Options @@ -80,9 +83,25 @@ wrangler deploy The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#parameters) object contains your project's [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform` property, along with [`context`](https://developers.cloudflare.com/workers/runtime-apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/cache/), and [`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), meaning that you can access it in hooks and endpoints: ```js -// @errors: 7031 +// @filename: ambient.d.ts +import { DurableObjectNamespace } from '@cloudflare/workers-types'; + +declare global { + namespace App { + interface Platform { + env: { + YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace; + }; + } + } +} +// @filename: +server.js +// ---cut--- +// @errors: 2355 2322 +/// file: +server.js +/** @type {import('./$types').RequestHandler} */ export async function POST({ request, platform }) { - const x = platform.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x'); + const x = platform?.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x'); } ``` 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 75f2203df301..26262314c338 100644 --- a/documentation/docs/25-build-and-deploy/80-adapter-netlify.md +++ b/documentation/docs/25-build-and-deploy/80-adapter-netlify.md @@ -11,11 +11,11 @@ This adapter will be installed by default when you use [`adapter-auto`](adapter- Install with `npm i -D @sveltejs/adapter-netlify`, then add the adapter to your `svelte.config.js`: ```js -// @errors: 2307 /// file: svelte.config.js import adapter from '@sveltejs/adapter-netlify'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { // default options are shown adapter: adapter({ @@ -30,6 +30,8 @@ export default { }) } }; + +export default config; ``` Then, make sure you have a [netlify.toml](https://docs.netlify.com/configure-builds/file-based-configuration) file in the project root. This will determine where to write static assets based on the `build.publish` settings, as per this sample configuration: @@ -51,11 +53,11 @@ New projects will use the current Node LTS version by default. However, if you'r SvelteKit supports [Netlify Edge Functions](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/). If you pass the option `edge: true` to the `adapter` function, server-side rendering will happen in a Deno-based edge function that's deployed close to the site visitor. If set to `false` (the default), the site will deploy to Node-based Netlify Functions. ```js -// @errors: 2307 /// file: svelte.config.js import adapter from '@sveltejs/adapter-netlify'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // will create a Netlify Edge Function using Deno-based @@ -64,6 +66,8 @@ export default { }) } }; + +export default config; ``` ## Netlify alternatives to SvelteKit functionality @@ -92,10 +96,14 @@ During compilation, redirect rules are automatically appended to your `_redirect With this adapter, SvelteKit endpoints are hosted as [Netlify Functions](https://docs.netlify.com/functions/overview/). Netlify function handlers have additional context, including [Netlify Identity](https://docs.netlify.com/visitor-access/identity/) information. You can access this context via the `event.platform.context` field inside your hooks and `+page.server` or `+layout.server` endpoints. These are [serverless functions](https://docs.netlify.com/functions/overview/) when the `edge` property is `false` in the adapter config or [edge functions](https://docs.netlify.com/edge-functions/overview/#app) when it is `true`. ```js -// @errors: 2705 7006 +// @filename: ambient.d.ts +/// +// @filename: +page.server.js +// ---cut--- /// file: +page.server.js +/** @type {import('./$types').PageServerLoad} */ export const load = async (event) => { - const context = event.platform.context; + const context = event.platform?.context; console.log(context); // shows up in your functions log in the Netlify app }; ``` 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 58e8079cda27..36666fdd75ce 100644 --- a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md +++ b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md @@ -11,17 +11,19 @@ This adapter will be installed by default when you use [`adapter-auto`](adapter- Install with `npm i -D @sveltejs/adapter-vercel`, then add the adapter to your `svelte.config.js`: ```js -// @errors: 2307 2345 /// file: svelte.config.js import adapter from '@sveltejs/adapter-vercel'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ // see below for options that can be set here }) } }; + +export default config; ``` ## Deployment configuration @@ -72,7 +74,8 @@ You may set the `images` config to control how Vercel builds your images. See th /// file: svelte.config.js import adapter from '@sveltejs/adapter-vercel'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { kit: { adapter: adapter({ images: { @@ -84,6 +87,8 @@ export default { }) } }; + +export default config; ``` ## Incremental Static Regeneration @@ -95,9 +100,9 @@ Vercel supports [Incremental Static Regeneration](https://vercel.com/docs/increm To add ISR to a route, include the `isr` property in your `config` object: ```js -// @errors: 2664 import { BYPASS_TOKEN } from '$env/static/private'; +/** @type {import('@sveltejs/adapter-vercel').Config} */ export const config = { isr: { expiration: 60, @@ -146,7 +151,6 @@ A list of valid query parameters that contribute to the cache key. Other paramet Vercel makes a set of [deployment-specific environment variables](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) available. Like other environment variables, these are accessible from `$env/static/private` and `$env/dynamic/private` (sometimes — more on that later), and inaccessible from their public counterparts. To access one of these variables from the client: ```js -// @errors: 2305 /// file: +layout.server.js import { VERCEL_COMMIT_REF } from '$env/static/private'; diff --git a/documentation/docs/30-advanced/20-hooks.md b/documentation/docs/30-advanced/20-hooks.md index 4a2239ad2240..04d9bf5967ad 100644 --- a/documentation/docs/30-advanced/20-hooks.md +++ b/documentation/docs/30-advanced/20-hooks.md @@ -249,6 +249,7 @@ This function runs once, when the server is created or the app starts in the bro > [!NOTE] If your environment supports top-level await, the `init` function is really no different from writing your initialisation logic at the top level of the module, but some environments — most notably, Safari — don't. ```js +// @errors: 2307 /// file: src/hooks.server.js import * as db from '$lib/server/database'; @@ -272,9 +273,8 @@ This function runs before `handle` and allows you to change how URLs are transla For example, you might have a `src/routes/[[lang]]/about/+page.svelte` page, which should be accessible as `/en/about` or `/de/ueber-uns` or `/fr/a-propos`. You could implement this with `reroute`: ```js +// @errors: 2345 2304 /// file: src/hooks.js -// @errors: 2345 -// @errors: 2304 /** @type {Record} */ const translated = { @@ -298,9 +298,8 @@ Using `reroute` will _not_ change the contents of the browser's address bar, or Since version 2.18, the `reroute` hook can be asynchronous, allowing it to (for example) fetch data from your backend to decide where to reroute to. Use this carefully and make sure it's fast, as it will delay navigation otherwise. If you need to fetch data, use the `fetch` provided as an argument. It has the [same benefits](load#Making-fetch-requests) as the `fetch` provided to `load` functions, with the caveat that `params` and `id` are unavailable to [`handleFetch`](#Server-hooks-handleFetch) because the route is not yet known. ```js +// @errors: 2345 2304 /// file: src/hooks.js -// @errors: 2345` -// @errors: 2304 /** @type {import('@sveltejs/kit').Reroute} */ export async function reroute({ url, fetch }) { @@ -323,6 +322,7 @@ export async function reroute({ url, fetch }) { This is a collection of _transporters_, which allow you to pass custom types — returned from `load` and form actions — across the server/client boundary. Each transporter contains an `encode` function, which encodes values on the server (or returns a falsy value for anything that isn't an instance of the type) and a corresponding `decode` function: ```js +// @errors: 2307 /// file: src/hooks.js import { Vector } from '$lib/math'; diff --git a/documentation/docs/30-advanced/40-service-workers.md b/documentation/docs/30-advanced/40-service-workers.md index f57dba4abc7e..23aea04e56e7 100644 --- a/documentation/docs/30-advanced/40-service-workers.md +++ b/documentation/docs/30-advanced/40-service-workers.md @@ -23,10 +23,23 @@ Inside the service worker you have access to the [`$service-worker` module]($ser 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. ```js -// @errors: 2339 +/// file: src/service-worker.js +// Disables access to DOM typings like `HTMLElement` which are not available +// inside a service worker and instantiates the correct globals +/// +/// +/// +// Ensures that the `$service-worker` import has proper type definitions /// +// Only necessary if you have an import from `$env/static/public` +/// + import { build, files, version } from '$service-worker'; +// The reassignment of `self` to `sw` allows you to type cast it in the process +// (this is the easiest way to do it without needing additional files) +const sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (self)); + // Create a unique cache name for this deployment const CACHE = `cache-${version}`; @@ -35,7 +48,7 @@ const ASSETS = [ ...files // everything in `static` ]; -self.addEventListener('install', (event) => { +sw.addEventListener('install', (event) => { // Create a new cache and add all files to it async function addFilesToCache() { const cache = await caches.open(CACHE); @@ -45,7 +58,7 @@ self.addEventListener('install', (event) => { event.waitUntil(addFilesToCache()); }); -self.addEventListener('activate', (event) => { +sw.addEventListener('activate', (event) => { // Remove previous cached data from disk async function deleteOldCaches() { for (const key of await caches.keys()) { @@ -56,7 +69,7 @@ self.addEventListener('activate', (event) => { event.waitUntil(deleteOldCaches()); }); -self.addEventListener('fetch', (event) => { +sw.addEventListener('fetch', (event) => { // ignore POST requests etc if (event.request.method !== 'GET') return; @@ -122,29 +135,6 @@ navigator.serviceWorker.register('/service-worker.js', { > [!NOTE] `build` and `prerendered` are empty arrays during development -## Type safety - -Setting up proper types for service workers requires some manual setup. Inside your `service-worker.js`, add the following to the top of your file: - -```original-js -/// -/// -/// -/// - -const sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (self)); -``` -```generated-ts -/// -/// -/// -/// - -const sw = self as unknown as ServiceWorkerGlobalScope; -``` - -This disables access to DOM typings like `HTMLElement` which are not available inside a service worker and instantiates the correct globals. The reassignment of `self` to `sw` allows you to type cast it in the process (there are a couple of ways to do this, but this is the easiest that requires no additional files). Use `sw` instead of `self` in the rest of the file. The reference to the SvelteKit types ensures that the `$service-worker` import has proper type definitions. If you import `$env/static/public` you either have to `// @ts-ignore` the import or add `/// ` to the reference types. - ## Other solutions SvelteKit's service worker implementation is designed to be easy to work with and is probably a good solution for most users. However, outside of SvelteKit, many PWA applications leverage the [Workbox](https://web.dev/learn/pwa/workbox) library. If you're used to using Workbox you may prefer [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html). diff --git a/documentation/docs/60-appendix/20-integrations.md b/documentation/docs/60-appendix/20-integrations.md index a4213c44da4a..4d9db6be59d2 100644 --- a/documentation/docs/60-appendix/20-integrations.md +++ b/documentation/docs/60-appendix/20-integrations.md @@ -10,9 +10,12 @@ Including [`vitePreprocess`](https://github.com/sveltejs/vite-plugin-svelte/blob // svelte.config.js import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { preprocess: [vitePreprocess()] }; + +export default config; ``` You will also need to use a preprocessor if you're using TypeScript with Svelte 4. TypeScript is supported natively in Svelte 5 if you're using only the type syntax. To use more complex TypeScript syntax in Svelte 5, you will need still need a preprocessor and can use `vitePreprocess({ script: true })`.