+
+
From 9724bc03eebfcaccf919b4311a9ba244f833f062 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 10:54:36 -0400
Subject: [PATCH 002/151] tweaks
---
.../04-advanced-loading/04-custom-dependencies/README.md | 1 +
.../04-advanced-loading/05-invalidate-all/README.md | 1 +
.../05-environment-variables/01-env-static-private/README.md | 4 ++--
.../01-env-static-private/app-a/src/routes/+page.svelte | 2 +-
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md
index bb0503d66..fcc47e099 100644
--- a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md
@@ -1,5 +1,6 @@
---
title: Custom dependencies
+path: /Europe/London
---
Calling `fetch(url)` inside a `load` function registers `url` as a dependency. Sometimes it's not appropriate to use `fetch`, in which case you can specify a dependency manually with the [`depends(url)`](https://kit.svelte.dev/docs/load#invalidation-manual-invalidation) function.
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md
index afd34b194..e5343d4ae 100644
--- a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md
@@ -1,5 +1,6 @@
---
title: invalidateAll
+path: /Europe/London
---
Finally, there's the nuclear option — `invalidateAll()`. This will indiscriminately re-run all `load` functions for the current page, regardless of what they depend on.
diff --git a/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/README.md b/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/README.md
index f6334fcd3..e7790132a 100644
--- a/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/README.md
+++ b/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/README.md
@@ -5,6 +5,8 @@ title: $env/static/private
Environment variables — like API keys and database credentials — can be added to a `.env` file, and they will be made available to your application.
> You can also use `.env.local` or `.env.[mode]` files — see the [Vite documentation](https://vitejs.dev/guide/env-and-mode.html#env-files) for more information). Make sure you add any files containing sensitive information to your `.gitignore` file!
+>
+> Environment variables in `process.env` are also available via `$env/static/private`.
In this exercise, we want to allow the user to enter the website if they know the correct passphrase, using an environment variable.
@@ -49,8 +51,6 @@ export const actions = {
The website is now accessible to anyone who knows the correct passphrase.
-> Environment variables in `process.env` are also available via `$env/static/private`.
-
## Keeping secrets
It's important that sensitive data doesn't accidentally end up being sent to the browser, where it could easily be stolen by hackers and scoundrels.
diff --git a/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/app-a/src/routes/+page.svelte
index a848d87bb..492ac6915 100644
--- a/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/app-a/src/routes/+page.svelte
+++ b/content/tutorial/04-advanced-sveltekit/05-environment-variables/01-env-static-private/app-a/src/routes/+page.svelte
@@ -5,7 +5,7 @@
From 5f4cc5d6336b4489377df171d13c8c748318ef6a Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 11:18:33 -0400
Subject: [PATCH 003/151] Remove legacy adapter (#342)
* remove filesystem adapter
* update README
---------
Co-authored-by: Rich Harris
---
README.md | 24 +--
backend/+server.js | 14 --
backend/README.md | 1 -
backend/[id]/+server.js | 17 --
backend/apps.js | 208 --------------------
backend/destroy/+server.js | 14 --
backend/ws.js | 33 ----
src/lib/client/adapters/filesystem/index.js | 74 -------
8 files changed, 12 insertions(+), 373 deletions(-)
delete mode 100644 backend/+server.js
delete mode 100644 backend/README.md
delete mode 100644 backend/[id]/+server.js
delete mode 100644 backend/apps.js
delete mode 100644 backend/destroy/+server.js
delete mode 100644 backend/ws.js
delete mode 100644 src/lib/client/adapters/filesystem/index.js
diff --git a/README.md b/README.md
index d99fc947c..33c60bc96 100644
--- a/README.md
+++ b/README.md
@@ -6,21 +6,21 @@ A soup-to-nuts interactive tutorial on how to build apps with Svelte.
This repo uses [pnpm](https://pnpm.io/).
-## Running the app
+## Developing the app
-First, run `node scripts/create-common-bundle`. This packages up everything that's needed to run a SvelteKit app (Vite, Esbuild, SvelteKit, Svelte compiler etc) which can subsequently be unpacked on a server to create and run and instance of a SvelteKit application (which powers the output window of the tutorial).
+First, run `node scripts/create-common-bundle`. This packages up everything that's needed to run a SvelteKit app (Vite, Esbuild, SvelteKit, Svelte compiler etc) which can subsequently be unpacked on a server to create and run and instance of a SvelteKit application (which powers the output window of the tutorial). Then, run `dev`:
-The next steps depend on whether you want to run this locally in filesystem mode, or in WebContainer mode. For now, it works with filesystem mode only locally. In future, it will run both locally and on the web (using [WebContainers](https://blog.stackblitz.com/posts/introducing-webcontainers/)).
+```bash
+node scripts/create-common-bundle
+pnpm dev
+```
-### Local/filesystem mode
+To build for production and run locally:
-1. add an `.env` file with `PUBLIC_USE_FILESYSTEM=true` in it
-2. Run the app locally with `pnpm dev` or `pnpm build && pnpm preview`.
-
-### WebContainer mode
-
-1. if an `.env` file exists, modify it so there's `PUBLIC_USE_FILESYSTEM=` in it
-2. Run the app locally with `pnpm dev` or `pnpm build && pnpm preview`.
+```bash
+pnpm build
+pnpm preview
+```
## Creating new tutorials
@@ -28,4 +28,4 @@ Tutorials live inside `content`. Each tutorial consists of a `README.md`, which
## Bumping tutorial dependencies
-Bump the dependency (for example Svelte) in both the root and the `content/common` `package.json`. In the root do `pnpm i` (to update `pnpm-lock.yaml`), in `content/common` do `npm i` (to update `package-lock.json`). After deployment things might be out of date because Vercel caches things, redeploy without cache in that case.
+Bump the dependency (for example Svelte) in both the root and the `content/common` `package.json`. In the root do `pnpm i` (to update `pnpm-lock.yaml`), in `content/common` do `npm i` (to update `package-lock.json`).
\ No newline at end of file
diff --git a/backend/+server.js b/backend/+server.js
deleted file mode 100644
index 951581de2..000000000
--- a/backend/+server.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { json } from '@sveltejs/kit';
-import { create } from './apps';
-
-/** @type {import('./$types').RequestHandler} */
-export async function POST({ request }) {
- return json(
- await create({
- files: await request.json()
- }),
- {
- status: 201 // should this be a 200?
- }
- );
-}
diff --git a/backend/README.md b/backend/README.md
deleted file mode 100644
index 39de3f70c..000000000
--- a/backend/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This used to live in src/routes/backend, but it makes it impossible to use with edge functions. Keeping it here in case we need it in future.
diff --git a/backend/[id]/+server.js b/backend/[id]/+server.js
deleted file mode 100644
index 918ddfefd..000000000
--- a/backend/[id]/+server.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { clear, update } from '../apps';
-
-/** @type {import('./$types').RequestHandler} */
-export async function PUT({ url, request, params }) {
- const { id } = params;
- const files = await request.json();
-
- if (url.searchParams.has('reset')) {
- clear({ id, files });
- }
-
- update({ id, files });
-
- return new Response(undefined, {
- status: 201
- });
-}
diff --git a/backend/apps.js b/backend/apps.js
deleted file mode 100644
index 80b0669d8..000000000
--- a/backend/apps.js
+++ /dev/null
@@ -1,208 +0,0 @@
-import fs from 'node:fs';
-import path from 'node:path';
-import { spawn } from 'node:child_process';
-import { createRequire } from 'node:module';
-import * as ports from 'port-authority';
-import { broadcast, ready } from './ws';
-
-/**
- * @typedef {{
- * process: import('child_process').ChildProcess,
- * filenames: string[]
- * }} App */
-
-fs.rmSync('.apps', { recursive: true, force: true });
-fs.mkdirSync('.apps', { recursive: true });
-
-// poor man's HMR, pending https://github.com/vitejs/vite/issues/7887
-// @ts-expect-error
-if (globalThis.__apps) {
- globalThis.__apps.forEach((app) => {
- app.process.kill();
- });
-}
-
-const require = createRequire(import.meta.url);
-const vite_pkg_file = require.resolve('vite/package.json');
-const vite_pkg = JSON.parse(fs.readFileSync(vite_pkg_file, 'utf-8'));
-const vite = path.resolve(vite_pkg_file, '..', vite_pkg.bin['vite']);
-
-/** @type {Map} */
-const apps = new Map();
-globalThis.__apps = apps;
-
-const hooks_src = `/** @type {import('@sveltejs/kit').Handle} */
-export async function handle({ event, resolve }) {
- const response = await resolve(event);
-
- response.headers.set('cross-origin-opener-policy', 'same-origin');
- response.headers.set('cross-origin-embedder-policy', 'require-corp');
- response.headers.set('cross-origin-resource-policy', 'cross-origin');
-
- return response;
-}`;
-
-/**
- * @param {{
- * files: import('$lib/types').FileStub[]
- * }} options
- */
-export async function create({ files }) {
- const id = String(Date.now());
- const filenames = write_files(id, files);
-
- // TODO this enables embedding on cross-origin sites, which is
- // necessary for the JSNation talk, but will currently break if an app
- // already has a src/hooks.server.js file (though it could be worked
- // around easily enough if necessary)
- if (!files.find((stub) => stub.name === '/src/hooks.server.js')) {
- fs.writeFileSync(`.apps/${id}/src/hooks.server.js`, hooks_src);
- }
-
- const port = await ports.find(3001);
-
- apps.set(id, {
- process: launch(id, String(port)),
- filenames
- });
-
- await ports.waitUntilBusy(port);
-
- await ready;
-
- return {
- id,
- port
- };
-}
-
-/**
- * @param {{
- * id: string;
- * files: import('$lib/types').FileStub[]
- * }} options
- */
-export function clear({ id, files }) {
- const app = apps.get(id);
-
- if (!app) {
- throw new Error(`app ${id} does not exist`);
- }
-
- const dir = `.apps/${id}`;
- const old_filenames = new Set(app.filenames);
-
- /** @type {string[]} */
- const filenames = [];
-
- for (const file of files) {
- if (file.type === 'file') {
- filenames.push(file.name);
- old_filenames.delete(file.name);
- }
- }
-
- for (const file of old_filenames) {
- if (fs.existsSync(dir + file)) {
- fs.unlinkSync(dir + file);
- }
- }
-
- app.filenames = filenames;
-}
-
-/**
- * @param {{
- * id: string;
- * files: import('$lib/types').FileStub[]
- * }} options
- */
-export function update({ id, files }) {
- if (!apps.has(id)) {
- throw new Error(`app ${id} does not exist`);
- }
-
- write_files(id, files);
-}
-
-/**
- * @param {{ id: string }} options
- */
-export function destroy({ id }) {
- const dir = `.apps/${id}`;
-
- fs.rmSync(dir, { recursive: true, force: true });
-
- apps.get(id)?.process.kill();
- apps.delete(id);
-}
-
-/**
- * @param {string} id
- * @param {string} port
- */
-function launch(id, port) {
- const cwd = `.apps/${id}`;
-
- const process = spawn('node', [vite, 'dev', '--port', port], {
- cwd
- });
-
- process.stdout.on('data', (data) => {
- broadcast({ id, data: data.toString(), type: 'stdout' });
- });
-
- process.stderr.on('data', (data) => {
- broadcast({ id, data: data.toString(), type: 'stderr' });
- });
-
- return process;
-}
-
-/**
- *
- * @param {string} file
- * @param {string | Buffer} contents
- */
-function write_if_changed(file, contents) {
- if (typeof contents === 'string' && fs.existsSync(file)) {
- const existing = fs.readFileSync(file, 'utf-8');
- if (contents === existing) return;
- }
-
- fs.mkdirSync(path.dirname(file), { recursive: true });
- fs.writeFileSync(file, contents);
-}
-
-/**
- *
- * @param {string} id
- * @param {import('$lib/types').FileStub[]} files
- */
-function write_files(id, files) {
- const dir = `.apps/${id}`;
-
- /** @type {string[]} */
- const filenames = [];
-
- for (const file of files) {
- if (file.type === 'file') {
- filenames.push(file.name);
-
- const dest = `${dir}/${file.name}`;
- let content = file.text ? file.contents : Buffer.from(file.contents, 'base64');
-
- if (file.name === '/src/app.html' && typeof content === 'string') {
- // TODO handle case where config.kit.files.template is different
- content = content.replace(
- '',
- ''
- );
- }
-
- write_if_changed(dest, content);
- }
- }
-
- return filenames;
-}
diff --git a/backend/destroy/+server.js b/backend/destroy/+server.js
deleted file mode 100644
index ad9c89efd..000000000
--- a/backend/destroy/+server.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { destroy } from '../apps';
-
-// this is implemented as a POST handler because it is
-// triggered by `navigator.sendBeacon` rather than `fetch`
-
-/** @type {import('./$types').RequestHandler} */
-export function POST({ url }) {
- const id = /** @type {string} */ (url.searchParams.get('id'));
- destroy({ id });
-
- return new Response(undefined, {
- status: 204
- });
-}
diff --git a/backend/ws.js b/backend/ws.js
deleted file mode 100644
index e02317c0d..000000000
--- a/backend/ws.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// import './websocket.js';
-import { WebSocketServer } from 'ws';
-
-// poor man's HMR, pending https://github.com/vitejs/vite/issues/7887
-// @ts-expect-error
-if (globalThis.__wss) globalThis.__wss.close();
-
-const wss = new WebSocketServer({ port: 4567 });
-globalThis.__wss = wss;
-
-/** @type {Set} */
-const connections = new Set();
-
-wss.on('connection', (ws) => {
- connections.add(ws);
-
- ws.on('close', () => {
- connections.delete(ws);
- });
-});
-
-export const ready = new Promise((fulfil) => {
- wss.on('listening', () => {
- fulfil(undefined);
- });
-});
-
-/** @param {any} data */
-export function broadcast(data) {
- for (const connection of connections) {
- connection.send(JSON.stringify(data));
- }
-}
diff --git a/src/lib/client/adapters/filesystem/index.js b/src/lib/client/adapters/filesystem/index.js
deleted file mode 100644
index d3bd0e6ba..000000000
--- a/src/lib/client/adapters/filesystem/index.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @param {import('$lib/types').Stub[]} stubs
- * @param {(progress: number, status: string) => void} cb
- * @returns {Promise}
- */
-export async function create(stubs, cb) {
- const res = await fetch('http://github.com/backend', {
- method: 'post',
- headers: {
- 'content-type': 'application/json'
- },
- body: JSON.stringify(stubs)
- });
-
- const { id, port } = await res.json();
-
- const ws = new WebSocket('ws://localhost:4567');
-
- ws.addEventListener('message', (event) => {
- const payload = JSON.parse(event.data);
- if (payload.id === id) {
- console[payload.type === 'stdout' ? 'log' : 'error'](payload.data);
- }
- });
-
- cb(100, 'Ready');
-
- return {
- base: `http://localhost:${port}`,
-
- /** @param {import('$lib/types').Stub[]} stubs */
- async reset(stubs) {
- await fetch(`/backend/${id}?reset`, {
- method: 'put',
- headers: {
- 'content-type': 'application/json'
- },
- body: JSON.stringify(stubs)
- });
-
- await new Promise((f) => setTimeout(f, 100)); // wait for chokidar
-
- return true; // always reload page, not worth optimizing for local dev at this point
- },
-
- /** @param {import('$lib/types').FileStub[]} stubs */
- async update(stubs) {
- await fetch(`/backend/${id}`, {
- method: 'put',
- headers: {
- 'content-type': 'application/json'
- },
- body: JSON.stringify(stubs)
- });
-
- await new Promise((f) => setTimeout(f, 100)); // wait for chokidar
-
- return will_restart_vite_dev_server(stubs);
- }
- };
-}
-
-/**
- * @param {import('$lib/types').Stub[]} stubs
- */
-function will_restart_vite_dev_server(stubs) {
- return stubs.some(
- (stub) =>
- stub.type === 'file' &&
- (stub.name === '/vite.config.js' ||
- stub.name === '/svelte.config.js' ||
- stub.name === '/.env')
- );
-}
From d2a5d253201be46f2ed6a0bb278f57b95b8b7166 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 11:26:06 -0400
Subject: [PATCH 004/151] inject client in src/error.html (#343)
* inject client in src/error.html
* Update src/lib/client/adapters/webcontainer/index.js
---------
Co-authored-by: Rich Harris
---
src/lib/client/adapters/webcontainer/index.js | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/lib/client/adapters/webcontainer/index.js b/src/lib/client/adapters/webcontainer/index.js
index 153de72d7..f0f0de6f9 100644
--- a/src/lib/client/adapters/webcontainer/index.js
+++ b/src/lib/client/adapters/webcontainer/index.js
@@ -274,11 +274,8 @@ function convert_stubs_to_tree(stubs, depth = 1) {
/** @param {import('$lib/types').FileStub} file */
function to_file(file) {
// special case
- if (file.name === '/src/app.html') {
- const contents = file.contents.replace(
- '',
- ''
- );
+ if (file.name === '/src/app.html' || file.name === '/src/error.html') {
+ const contents = file.contents + '';
return {
file: { contents }
From 5a8506224ee7a069a9878036d2b38f0f67f772e7 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 12:04:34 -0400
Subject: [PATCH 005/151] preserve state when renaming file (#344)
* preserve state when renaming file
* actually on second thoughts
---------
Co-authored-by: Rich Harris
---
src/routes/tutorial/[slug]/filetree/Filetree.svelte | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/routes/tutorial/[slug]/filetree/Filetree.svelte b/src/routes/tutorial/[slug]/filetree/Filetree.svelte
index 84d651211..fa71de0aa 100644
--- a/src/routes/tutorial/[slug]/filetree/Filetree.svelte
+++ b/src/routes/tutorial/[slug]/filetree/Filetree.svelte
@@ -4,7 +4,7 @@
import Folder from './Folder.svelte';
import * as context from './context.js';
import Modal from '$lib/components/Modal.svelte';
- import { files, solution, reset_files, create_directories } from '../state.js';
+ import { files, solution, reset_files, create_directories, selected_name } from '../state.js';
import { afterNavigate } from '$app/navigation';
/** @type {import('$lib/types').Exercise} */
@@ -93,10 +93,16 @@
}
}
+ const was_selected = $selected_name === to_rename.name;
+
to_rename.basename = /** @type {string} */ (new_full_name.split('/').pop());
to_rename.name = new_full_name;
reset_files([...$files, ...create_directories(new_full_name, $files)]);
+
+ if (was_selected) {
+ dispatch('select', { name: new_full_name });
+ }
},
remove: async (file) => {
From 0486052aa9c326cd700965c71f7a487a4df4704d Mon Sep 17 00:00:00 2001
From: tomoam <29677552+tomoam@users.noreply.github.com>
Date: Sun, 9 Apr 2023 01:48:14 +0900
Subject: [PATCH 006/151] fix: accept autocompletions with Tab key without
losing focus (#346)
---
src/routes/tutorial/[slug]/Editor.svelte | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/src/routes/tutorial/[slug]/Editor.svelte b/src/routes/tutorial/[slug]/Editor.svelte
index f8c2e1cf2..ac9461abb 100644
--- a/src/routes/tutorial/[slug]/Editor.svelte
+++ b/src/routes/tutorial/[slug]/Editor.svelte
@@ -206,15 +206,6 @@
{
- if (e.key === 'Tab') {
- preserve_editor_focus = false;
-
- setTimeout(() => {
- preserve_editor_focus = true;
- }, 200);
- }
- }}
on:focusin={() => {
clearTimeout(remove_focus_timeout);
preserve_editor_focus = true;
From 3e122356edd7c9bcac2a0f02fd171e8dfa5add20 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 12:49:45 -0400
Subject: [PATCH 007/151] reinstate ping mechanism (#345)
* reinstate ping mechanism
* tidy up __client.js a bit
* fix 298
---------
Co-authored-by: Rich Harris
---
content/tutorial/common/src/__client.js | 143 ++++++++---------------
src/routes/tutorial/[slug]/Output.svelte | 21 +++-
2 files changed, 68 insertions(+), 96 deletions(-)
diff --git a/content/tutorial/common/src/__client.js b/content/tutorial/common/src/__client.js
index 1a419ed0b..a6741586f 100644
--- a/content/tutorial/common/src/__client.js
+++ b/content/tutorial/common/src/__client.js
@@ -1,69 +1,36 @@
-window.addEventListener('message', async (e) => {
- if (e.data.type === 'fetch') {
- const names = e.data.names;
-
- const transformed = await Promise.all(
- names.map(async (name) => {
- const res = await fetch(name);
- return {
- name,
- code: await res.text()
- };
- })
- );
-
- const css_files = [];
-
- for (const { name, code } of transformed) {
- if (
- name.endsWith('.svelte') &&
- code.includes('svelte&type=style&lang.css')
- ) {
- css_files.push(name + '?svelte&type=style&lang.css');
- }
- }
-
- if (css_files.length > 0) {
- const css_transformed = await Promise.all(
- css_files.map(async (name) => {
- const res = await fetch(name);
- return {
- name,
- code: await res.text()
- };
- })
- );
-
- transformed.push(...css_transformed);
- }
+function post(data) {
+ parent.postMessage(data, '*');
+}
- parent.postMessage(
- {
- type: 'fetch-result',
- data: transformed
- },
- '*'
- );
- }
-});
+function ping() {
+ post({
+ type: 'ping',
+ path: location.pathname + location.search + location.hash
+ });
+}
-let can_focus = false;
+function pause() {
+ post({ type: 'ping-pause' });
+}
-window.addEventListener('pointerdown', (e) => {
- can_focus = true;
-});
+// Hack into the alert that's used in some tutorials and send a message prior to the alert,
+// else the parent thinks we lost contact and wrongfully reloads the page.
+// The drawback is that alert is no longer blocking, but no tutorial relies on this.
+const alert = window.alert;
+window.alert = (message) => {
+ pause();
-window.addEventListener('pointerup', (e) => {
- can_focus = false;
-});
+ setTimeout(() => {
+ alert(message);
+ });
+};
-window.addEventListener('keydown', (e) => {
- can_focus = true;
-});
+let can_focus = false;
-window.addEventListener('keyup', (e) => {
- can_focus = false;
-});
+window.addEventListener('pointerdown', (e) => can_focus = true);
+window.addEventListener('pointerup', (e) => can_focus = false);
+window.addEventListener('keydown', (e) => can_focus = true);
+window.addEventListener('keyup', (e) => can_focus = false);
/**
* The iframe sometimes takes focus control in ways we can't prevent
@@ -78,12 +45,7 @@ window.addEventListener('focusin', (e) => {
if (e.target.tagName === 'BODY' && e.relatedTarget) return;
// otherwise, broadcast an event that causes the editor to reclaim focus
- parent.postMessage(
- {
- type: 'iframe_took_focus'
- },
- '*'
- );
+ post({ type: 'iframe_took_focus' });
});
window.addEventListener('click', (e) => {
@@ -102,47 +64,38 @@ window.addEventListener('click', (e) => {
}
});
-function ping() {
- parent.postMessage(
- {
- type: 'ping',
- data: {
- path: location.pathname + location.search + location.hash
- }
- },
- '*'
- );
-}
+window.addEventListener('visibilitychange', () => {
+ if (document.visibilityState === 'visible') {
+ ping();
+ } else {
+ pause();
+ }
+});
+
+let previous_href = location.href;
-let pre_url = location.href;
const url_observer = new MutationObserver(() => {
- if (location.href !== pre_url) {
- pre_url = location.href;
+ if (location.href !== previous_href) {
+ previous_href = location.href;
ping();
}
});
-url_observer.observe(document, { subtree: true, childList: true, attributes: true });
+url_observer.observe(document, {
+ subtree: true,
+ childList: true,
+ attributes: true
+});
+
+setInterval(ping, 100);
ping();
if (import.meta.hot) {
import.meta.hot.on('vite:beforeUpdate', (event) => {
- parent.postMessage(
- {
- type: 'hmr',
- data: event.updates
- },
- '*'
- );
+ post({ type: 'hmr', data: event.updates });
});
import.meta.hot.on('svelte:warnings', (data) => {
- parent.postMessage(
- {
- type: 'warnings',
- data
- },
- '*'
- );
+ post({ type: 'warnings', data });
});
}
diff --git a/src/routes/tutorial/[slug]/Output.svelte b/src/routes/tutorial/[slug]/Output.svelte
index 59b94af4e..013661cb2 100644
--- a/src/routes/tutorial/[slug]/Output.svelte
+++ b/src/routes/tutorial/[slug]/Output.svelte
@@ -34,6 +34,13 @@
};
});
+ afterNavigate(() => {
+ clearTimeout(timeout);
+ });
+
+ /** @type {any} */
+ let timeout;
+
/** @param {MessageEvent} e */
async function handle_message(e) {
if (e.origin !== $base) return;
@@ -41,8 +48,20 @@
if (paused) return;
if (e.data.type === 'ping') {
- path = e.data.data.path ?? path;
+ path = e.data.path;
loading = false;
+
+ clearTimeout(timeout);
+ timeout = setTimeout(() => {
+ if (dev && !iframe) return;
+
+ // we lost contact, refresh the page
+ loading = true;
+ set_iframe_src($base + path);
+ loading = false;
+ }, 1000);
+ } else if (e.data.type === 'ping-pause') {
+ clearTimeout(timeout);
} else if (e.data.type === 'warnings') {
warnings.update(($warnings) => ({
...$warnings,
From 38d727edb0f3b8caea4f24610ef1e738224f6361 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 13:12:18 -0400
Subject: [PATCH 008/151] vim mode (#253)
* vim mode
* enable vim via ?vim=true
---------
Co-authored-by: Rich Harris
---
package.json | 2 ++
pnpm-lock.yaml | 20 ++++++++++++++++++++
src/routes/tutorial/[slug]/Editor.svelte | 22 +++++++++++++++++++---
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index d95a64687..ca2b591e1 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"@codemirror/lang-javascript": "^6.1.4",
"@codemirror/language": "^6.6.0",
"@codemirror/lint": "^6.2.0",
+ "@codemirror/search": "^6.3.0",
"@codemirror/state": "^6.2.0",
"@codemirror/view": "^6.9.2",
"@fontsource/roboto-mono": "^4.5.10",
@@ -48,6 +49,7 @@
"@lezer/javascript": "^1.4.1",
"@lezer/lr": "^1.3.3",
"@replit/codemirror-lang-svelte": "^6.0.0",
+ "@replit/codemirror-vim": "^6.0.9",
"@rich_harris/svelte-split-pane": "^1.1.0",
"@webcontainer/api": "^1.1.0",
"adm-zip": "^0.5.10",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 401515604..980691d88 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,6 +8,7 @@ specifiers:
'@codemirror/lang-javascript': ^6.1.4
'@codemirror/language': ^6.6.0
'@codemirror/lint': ^6.2.0
+ '@codemirror/search': ^6.3.0
'@codemirror/state': ^6.2.0
'@codemirror/view': ^6.9.2
'@fontsource/roboto-mono': ^4.5.10
@@ -17,6 +18,7 @@ specifiers:
'@lezer/lr': ^1.3.3
'@playwright/test': ^1.31.2
'@replit/codemirror-lang-svelte': ^6.0.0
+ '@replit/codemirror-vim': ^6.0.9
'@rich_harris/svelte-split-pane': ^1.1.0
'@sveltejs/adapter-vercel': 2.3.1
'@sveltejs/kit': ^1.15.0
@@ -54,6 +56,7 @@ dependencies:
'@codemirror/lang-javascript': 6.1.4
'@codemirror/language': 6.6.0
'@codemirror/lint': 6.2.0
+ '@codemirror/search': 6.3.0
'@codemirror/state': 6.2.0
'@codemirror/view': 6.9.2
'@fontsource/roboto-mono': 4.5.10
@@ -62,6 +65,7 @@ dependencies:
'@lezer/javascript': 1.4.1
'@lezer/lr': 1.3.3
'@replit/codemirror-lang-svelte': 6.0.0_ybny7xhlf2ysg4majw54z4nkly
+ '@replit/codemirror-vim': 6.0.11_43oovqgcdaxzhub7wnzsdexoq4
'@rich_harris/svelte-split-pane': 1.1.0_svelte@3.57.0
'@webcontainer/api': 1.1.0
adm-zip: 0.5.10
@@ -732,6 +736,22 @@ packages:
'@lezer/lr': 1.3.3
dev: false
+ /@replit/codemirror-vim/6.0.11_43oovqgcdaxzhub7wnzsdexoq4:
+ resolution: {integrity: sha512-b3umG+3DR9LfNjrPBk1849Cp8WHgFbYFhlFvGg62br03NdVquVKxaQonK7xA8WGurzQeQOpBW+hhr7mzZxWksA==}
+ peerDependencies:
+ '@codemirror/commands': ^6.0.0
+ '@codemirror/language': ^6.1.0
+ '@codemirror/search': ^6.2.0
+ '@codemirror/state': ^6.0.1
+ '@codemirror/view': ^6.0.3
+ dependencies:
+ '@codemirror/commands': 6.2.2
+ '@codemirror/language': 6.6.0
+ '@codemirror/search': 6.3.0
+ '@codemirror/state': 6.2.0
+ '@codemirror/view': 6.9.2
+ dev: false
+
/@rich_harris/svelte-split-pane/1.1.0_svelte@3.57.0:
resolution: {integrity: sha512-gxDfPqRSRx11/t+cs5ao0pXzKSO6CiBDmbcVwD8o/zToNZZTZjompoRmvRRICT9OhPxwwl/87nXJEToorPyICg==}
peerDependencies:
diff --git a/src/routes/tutorial/[slug]/Editor.svelte b/src/routes/tutorial/[slug]/Editor.svelte
index ac9461abb..caa01f7bc 100644
--- a/src/routes/tutorial/[slug]/Editor.svelte
+++ b/src/routes/tutorial/[slug]/Editor.svelte
@@ -78,10 +78,26 @@
}
}
+ let installed_vim = false;
+
/** @param {import('$lib/types').Stub[]} $files */
- function reset($files) {
+ async function reset($files) {
if (skip_reset) return;
+ let should_install_vim = localStorage.getItem('vim') === 'true';
+
+ const q = new URLSearchParams(location.search);
+ if (q.has('vim')) {
+ should_install_vim = q.get('vim') === 'true';
+ localStorage.setItem('vim', should_install_vim.toString());
+ }
+
+ if (!installed_vim && should_install_vim) {
+ installed_vim = true;
+ const { vim } = await import('@replit/codemirror-vim');
+ extensions.push(vim());
+ }
+
for (const file of $files) {
if (file.type !== 'file') continue;
@@ -174,11 +190,11 @@
skip_reset = true;
});
- afterNavigate(() => {
+ afterNavigate(async () => {
skip_reset = false;
editor_states.clear();
- reset($files);
+ await reset($files);
if (editor_view) {
// could be false if onMount returned early
From 736de99fbc5de497e11ad9daae9ac82f606ef70e Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 14:50:23 -0400
Subject: [PATCH 009/151] condense intro spiel
---
.../01-introducing-sveltekit/README.md | 18 ++++++++++++++++--
.../01-concepts/02-project-structure/README.md | 15 ---------------
.../01-concepts/03-server-and-client/README.md | 13 -------------
.../03-sveltekit/01-concepts/meta.json | 2 +-
4 files changed, 17 insertions(+), 31 deletions(-)
delete mode 100644 content/tutorial/03-sveltekit/01-concepts/02-project-structure/README.md
delete mode 100644 content/tutorial/03-sveltekit/01-concepts/03-server-and-client/README.md
diff --git a/content/tutorial/03-sveltekit/01-concepts/01-introducing-sveltekit/README.md b/content/tutorial/03-sveltekit/01-concepts/01-introducing-sveltekit/README.md
index 90592b276..d0e748c7b 100644
--- a/content/tutorial/03-sveltekit/01-concepts/01-introducing-sveltekit/README.md
+++ b/content/tutorial/03-sveltekit/01-concepts/01-introducing-sveltekit/README.md
@@ -2,7 +2,7 @@
title: What is SvelteKit?
---
-SvelteKit is a framework for building extremely high-performance web apps. Whereas Svelte is a _component framework_, SvelteKit is an _app framework_ (or 'metaframework', depending on who you ask) that solves the tricky problems of building something production-ready:
+Whereas Svelte is a _component framework_, SvelteKit is an _app framework_ (or 'metaframework', depending on who you ask) that solves the tricky problems of building something production-ready:
- Routing
- Server-side rendering
@@ -18,4 +18,18 @@ SvelteKit is a framework for building extremely high-performance web apps. Where
SvelteKit apps are server-rendered by default (like traditional 'multi-page apps' or MPAs) for excellent first load performance and SEO characteristics, but can then transition to client-side navigation (like modern 'single-page apps' or SPAs) to avoid jankily reloading everything (including things like third-party analytics code) when the user navigates. They can run anywhere JavaScript runs, though — as we'll see — your users may not need to run any JavaScript at all.
-If that sounds complicated, worry not: SvelteKit is the framework that grows with you! Start simple and add new features as they come. This tutorial will go over the core concepts, while the [Advanced SvelteKit](/tutorial/handle) tutorial teaches you how to tackle more complex use cases.
+If that sounds complicated, worry not: SvelteKit is the framework that grows with you! Start simple and add new features as you need them.
+
+## Project structure
+
+On the right, in the file tree viewer, you'll see a handful of files that SvelteKit expects to find in a project.
+
+`package.json` will be familiar if you've worked with Node.js before. It lists the project's dependencies — including `svelte` and `@sveltejs/kit` — and a variety of `scripts` for interacting with the SvelteKit CLI. (We're currently running `npm run dev` in the bottom window.)
+
+> Note that it also specifies `"type": "module"`, which means that `.js` files are treated as native JavaScript modules by default, rather than the legacy CommonJS format.
+
+`svelte.config.js` contains your project configuration. We don't need to worry about this file for now, but if you're curious, [visit the documentation](https://kit.svelte.dev/docs/configuration).
+
+`src` is where your app's source code goes. `src/app.html` is your page template (SvelteKit replaces the `%sveltekit.head%` and `%sveltekit.body%` as appropriate), and `src/routes` defines the [routes](/tutorial/pages) of your app.
+
+Finally, `static` contains any assets (like a `favicon.png` or a `robots.txt`) that should be included when your app is deployed.
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/01-concepts/02-project-structure/README.md b/content/tutorial/03-sveltekit/01-concepts/02-project-structure/README.md
deleted file mode 100644
index 46a7c971a..000000000
--- a/content/tutorial/03-sveltekit/01-concepts/02-project-structure/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: Project structure
----
-
-On the right, in the file tree viewer, you'll see a handful of files that SvelteKit expects to find in a project.
-
-`package.json` will be familiar if you've worked with Node.js before. It lists the project's dependencies — including `svelte` and `@sveltejs/kit` — and a variety of `scripts` for interacting with the SvelteKit CLI. (We're currently running `npm run dev` in the bottom window.)
-
-> Note that it also specifies `"type": "module"`, which means that `.js` files are treated as native JavaScript modules by default, rather than the legacy CommonJS format.
-
-`svelte.config.js` contains your project configuration. We don't need to worry about this file for now, but if you're curious, [visit the documentation](https://kit.svelte.dev/docs/configuration).
-
-`src` is where your app's source code goes. `src/app.html` is your page template (SvelteKit replaces the `%sveltekit.head%` and `%sveltekit.body%` as appropriate), and `src/routes` defines the [routes](/tutorial/pages) of your app.
-
-Finally, `static` contains any assets (like a `favicon.png` or a `robots.txt`) that should be included when your app is deployed.
diff --git a/content/tutorial/03-sveltekit/01-concepts/03-server-and-client/README.md b/content/tutorial/03-sveltekit/01-concepts/03-server-and-client/README.md
deleted file mode 100644
index e9b409b79..000000000
--- a/content/tutorial/03-sveltekit/01-concepts/03-server-and-client/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: Server and client
----
-
-A SvelteKit app can be thought of as two distinct entities working in tandem — the _server_ and the _client_.
-
-'Server' is, perhaps, a confusing word since your app will often be running in a _serverless_ environment (cloud/edge functions) or might even be deployed as a set of completely static files. But it's the best we've got. The server's basic job is to turn a request into a response.
-
-'Client' refers to the JavaScript that loads in the browser.
-
-SvelteKit makes the two communicate with each other seamlessly. On the initial page load, the server renders the HTML, meaning content is visible as quickly as possible. The client then takes over in a process called 'hydration', so that subsequent navigations happen without full page reloads. It will request additional code and data from the server as needed.
-
-> You can [adjust this behavior](https://kit.svelte.dev/docs/page-options) as needed. SvelteKit is very versatile!
diff --git a/content/tutorial/03-sveltekit/01-concepts/meta.json b/content/tutorial/03-sveltekit/01-concepts/meta.json
index 75021ded3..fd70acd69 100644
--- a/content/tutorial/03-sveltekit/01-concepts/meta.json
+++ b/content/tutorial/03-sveltekit/01-concepts/meta.json
@@ -1,3 +1,3 @@
{
- "title": "Concepts"
+ "title": "Introduction"
}
From 5955e9fd2fe5f895f23ae41768d5dbec39255c2c Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 14:57:24 -0400
Subject: [PATCH 010/151] move some exercises around
---
.../04-advanced-loading/01-universal-load-functions}/README.md | 0
.../{01-await-parent => 02-await-parent}/README.md | 0
.../app-a/src/routes/+layout.server.js | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/sum/+layout.js | 0
.../app-a/src/routes/sum/+page.js | 0
.../app-a/src/routes/sum/+page.svelte | 0
.../app-b/src/routes/+layout.server.js | 0
.../app-b/src/routes/sum/+layout.js | 0
.../app-b/src/routes/sum/+page.js | 0
.../README.md | 0
.../app-a/src/routes/+page.js | 0
.../app-a/src/routes/+page.server.js | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/BoringComponent.svelte | 0
.../app-a/src/routes/CoolComponent.svelte | 0
.../app-b/src/routes/+page.js | 0
.../{03-invalidation => 04-invalidation}/README.md | 0
.../app-a/src/routes/+layout.js | 0
.../app-a/src/routes/+layout.svelte | 0
.../app-a/src/routes/[...timezone]/+page.js | 0
.../app-a/src/routes/[...timezone]/+page.svelte | 0
.../app-a/src/routes/api/now/+server.js | 0
.../app-b/src/routes/[...timezone]/+page.svelte | 0
.../{04-custom-dependencies => 05-custom-dependencies}/README.md | 0
.../app-b/src/routes/+layout.js | 0
.../app-b/src/routes/[...timezone]/+page.svelte | 0
.../{05-invalidate-all => 06-invalidate-all}/README.md | 0
.../app-b/src/routes/+layout.js | 0
.../app-b/src/routes/[...timezone]/+page.svelte | 0
30 files changed, 0 insertions(+), 0 deletions(-)
rename content/tutorial/{03-sveltekit/03-loading-data/03-universal-load-functions => 04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-a/src/routes/+layout.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-a/src/routes/sum/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-a/src/routes/sum/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-a/src/routes/sum/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-b/src/routes/+layout.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-b/src/routes/sum/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{01-await-parent => 02-await-parent}/app-b/src/routes/sum/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-a/src/routes/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-a/src/routes/+page.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-a/src/routes/BoringComponent.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-a/src/routes/CoolComponent.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-using-both-load-functions => 03-using-both-load-functions}/app-b/src/routes/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-a/src/routes/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-a/src/routes/[...timezone]/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-a/src/routes/[...timezone]/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-a/src/routes/api/now/+server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-invalidation => 04-invalidation}/app-b/src/routes/[...timezone]/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{04-custom-dependencies => 05-custom-dependencies}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{04-custom-dependencies => 05-custom-dependencies}/app-b/src/routes/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{04-custom-dependencies => 05-custom-dependencies}/app-b/src/routes/[...timezone]/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{05-invalidate-all => 06-invalidate-all}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{05-invalidate-all => 06-invalidate-all}/app-b/src/routes/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{05-invalidate-all => 06-invalidate-all}/app-b/src/routes/[...timezone]/+page.svelte (100%)
diff --git a/content/tutorial/03-sveltekit/03-loading-data/03-universal-load-functions/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/03-loading-data/03-universal-load-functions/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/+layout.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/+layout.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+layout.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-a/src/routes/sum/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/+layout.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/+layout.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/+layout.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/sum/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/sum/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/sum/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-await-parent/app-b/src/routes/sum/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/BoringComponent.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/CoolComponent.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-b/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-b/src/routes/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-b/src/routes/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-b/src/routes/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/+layout.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/[...timezone]/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/[...timezone]/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/[...timezone]/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/[...timezone]/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/[...timezone]/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/[...timezone]/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/[...timezone]/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/[...timezone]/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/api/now/+server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/api/now/+server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-a/src/routes/api/now/+server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-a/src/routes/api/now/+server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-b/src/routes/[...timezone]/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-b/src/routes/[...timezone]/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-invalidation/app-b/src/routes/[...timezone]/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-invalidation/app-b/src/routes/[...timezone]/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/app-b/src/routes/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/app-b/src/routes/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/app-b/src/routes/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/app-b/src/routes/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/app-b/src/routes/[...timezone]/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/app-b/src/routes/[...timezone]/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/04-custom-dependencies/app-b/src/routes/[...timezone]/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-custom-dependencies/app-b/src/routes/[...timezone]/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/app-b/src/routes/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/app-b/src/routes/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/app-b/src/routes/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/app-b/src/routes/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/app-b/src/routes/[...timezone]/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/app-b/src/routes/[...timezone]/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/05-invalidate-all/app-b/src/routes/[...timezone]/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/06-invalidate-all/app-b/src/routes/[...timezone]/+page.svelte
From d7fc28832d324561d1721b0be58fc1ffe31d0d0d Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 16:13:06 -0400
Subject: [PATCH 011/151] universal load function example
---
.../01-universal-load-functions/README.md | 33 +++++++++++++------
.../app-a/src/routes/+layout.svelte | 22 +++++++++++++
.../app-a/src/routes/+page.svelte | 1 +
.../app-a/src/routes/blue/+page.server.js | 8 +++++
.../app-a/src/routes/blue/+page.svelte | 1 +
.../app-a/src/routes/blue/blue.svelte | 1 +
.../app-a/src/routes/green/+page.server.js | 8 +++++
.../app-a/src/routes/green/+page.svelte | 1 +
.../app-a/src/routes/green/green.svelte | 1 +
.../app-a/src/routes/red/+page.server.js | 8 +++++
.../app-a/src/routes/red/+page.svelte | 1 +
.../app-a/src/routes/red/red.svelte | 1 +
.../app-b/src/routes/+layout.svelte | 26 +++++++++++++++
.../app-b/src/routes/blue/+page.js | 8 +++++
.../app-b/src/routes/blue/+page.server.js | 1 +
.../app-b/src/routes/green/+page.js | 8 +++++
.../app-b/src/routes/green/+page.server.js | 1 +
.../app-b/src/routes/red/+page.js | 8 +++++
.../app-b/src/routes/red/+page.server.js | 1 +
19 files changed, 129 insertions(+), 10 deletions(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/blue.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/green.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/red.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/+layout.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.js
create mode 100644 content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md
index 2c09853bb..100d5cec5 100644
--- a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/README.md
@@ -2,12 +2,7 @@
title: Universal load functions
---
-> Coming soon
-
-In the meantime, read the [documentation](https://kit.svelte.dev/docs/load#shared-vs-server) to learn more about the distinction between server `load` functions and universal `load` functions.
-
-
+Read the [documentation](https://kit.svelte.dev/docs/load#shared-vs-server) to learn more about the distinction between server `load` functions and universal `load` functions, and when to use which.
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..5a88cab0e
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+layout.svelte
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..1c96fb5c5
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+
pick a colour
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.server.js
new file mode 100644
index 000000000..4acf4c9df
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.server.js
@@ -0,0 +1,8 @@
+import component from './blue.svelte';
+
+export function load() {
+ return {
+ color: 'blue',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.svelte
new file mode 100644
index 000000000..866c837c8
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/+page.svelte
@@ -0,0 +1 @@
+
blue
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/blue.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/blue.svelte
new file mode 100644
index 000000000..3cc5b00b2
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/blue/blue.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.server.js
new file mode 100644
index 000000000..ca7ce1a2a
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.server.js
@@ -0,0 +1,8 @@
+import component from './green.svelte';
+
+export function load() {
+ return {
+ color: 'green',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.svelte
new file mode 100644
index 000000000..5c1fed3c6
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/+page.svelte
@@ -0,0 +1 @@
+
green
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/green.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/green.svelte
new file mode 100644
index 000000000..bce0f6f2b
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/green/green.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.server.js
new file mode 100644
index 000000000..cb781857b
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.server.js
@@ -0,0 +1,8 @@
+import component from './red.svelte';
+
+export function load() {
+ return {
+ color: 'red',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.svelte
new file mode 100644
index 000000000..40cc9dd71
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/+page.svelte
@@ -0,0 +1 @@
+
red
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/red.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/red.svelte
new file mode 100644
index 000000000..90b92b793
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-a/src/routes/red/red.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/+layout.svelte
new file mode 100644
index 000000000..4a9e4726a
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/+layout.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.js
new file mode 100644
index 000000000..4acf4c9df
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.js
@@ -0,0 +1,8 @@
+import component from './blue.svelte';
+
+export function load() {
+ return {
+ color: 'blue',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.server.js
new file mode 100644
index 000000000..bfb388899
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/blue/+page.server.js
@@ -0,0 +1 @@
+__delete
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.js
new file mode 100644
index 000000000..ca7ce1a2a
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.js
@@ -0,0 +1,8 @@
+import component from './green.svelte';
+
+export function load() {
+ return {
+ color: 'green',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.server.js
new file mode 100644
index 000000000..bfb388899
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/green/+page.server.js
@@ -0,0 +1 @@
+__delete
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.js
new file mode 100644
index 000000000..cb781857b
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.js
@@ -0,0 +1,8 @@
+import component from './red.svelte';
+
+export function load() {
+ return {
+ color: 'red',
+ component
+ };
+}
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.server.js
new file mode 100644
index 000000000..bfb388899
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/01-universal-load-functions/app-b/src/routes/red/+page.server.js
@@ -0,0 +1 @@
+__delete
\ No newline at end of file
From 0994534887b74665b560d02b08a577a8f38e0bd9 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Sat, 8 Apr 2023 16:13:48 -0400
Subject: [PATCH 012/151] swap order
---
.../README.md | 0
.../app-a/src/routes/+page.js | 0
.../app-a/src/routes/+page.server.js | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/BoringComponent.svelte | 0
.../app-a/src/routes/CoolComponent.svelte | 0
.../app-b/src/routes/+page.js | 0
.../{02-await-parent => 03-await-parent}/README.md | 0
.../app-a/src/routes/+layout.server.js | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/sum/+layout.js | 0
.../app-a/src/routes/sum/+page.js | 0
.../app-a/src/routes/sum/+page.svelte | 0
.../app-b/src/routes/+layout.server.js | 0
.../app-b/src/routes/sum/+layout.js | 0
.../app-b/src/routes/sum/+page.js | 0
16 files changed, 0 insertions(+), 0 deletions(-)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-a/src/routes/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-a/src/routes/+page.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-a/src/routes/BoringComponent.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-a/src/routes/CoolComponent.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{03-using-both-load-functions => 02-using-both-load-functions}/app-b/src/routes/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-a/src/routes/+layout.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-a/src/routes/sum/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-a/src/routes/sum/+page.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-a/src/routes/sum/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-b/src/routes/+layout.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-b/src/routes/sum/+layout.js (100%)
rename content/tutorial/04-advanced-sveltekit/04-advanced-loading/{02-await-parent => 03-await-parent}/app-b/src/routes/sum/+page.js (100%)
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/BoringComponent.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/BoringComponent.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/CoolComponent.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-a/src/routes/CoolComponent.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-b/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-b/src/routes/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-using-both-load-functions/app-b/src/routes/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-using-both-load-functions/app-b/src/routes/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/README.md b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/README.md
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+layout.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+layout.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/+layout.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+page.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.svelte b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-a/src/routes/sum/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-a/src/routes/sum/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/+layout.server.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/+layout.server.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/+layout.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+layout.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/sum/+layout.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+layout.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/sum/+layout.js
diff --git a/content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+page.js b/content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/sum/+page.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/04-advanced-loading/02-await-parent/app-b/src/routes/sum/+page.js
rename to content/tutorial/04-advanced-sveltekit/04-advanced-loading/03-await-parent/app-b/src/routes/sum/+page.js
From 8d475dc0730dc385a8edc6b60761b7af560c8d00 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 09:30:28 -0400
Subject: [PATCH 013/151] POST/PUT/DELETE
---
.../05-api-routes/02-post-handlers/README.md | 87 ++++++++++++++
.../app-a/src/lib/server/database.js | 39 +++++++
.../app-a/src/routes/+page.server.js | 14 +++
.../app-a/src/routes/+page.svelte | 86 ++++++++++++++
.../app-a/src/routes/remove.svg | 3 +
.../app-b/src/routes/+page.svelte | 99 ++++++++++++++++
.../app-b/src/routes/todo/+server.js | 11 ++
.../02-post-put-patch-delete/README.md | 5 -
.../app-a/src/routes/+page.svelte | 1 -
.../05-api-routes/03-other-handlers/README.md | 61 ++++++++++
.../app-b/src/routes/+page.svelte | 109 ++++++++++++++++++
.../app-b/src/routes/todo/[id]/+server.js | 16 +++
12 files changed, 525 insertions(+), 6 deletions(-)
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
delete mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/README.md
delete mode 100644 content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md
new file mode 100644
index 000000000..fd604f7a1
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md
@@ -0,0 +1,87 @@
+---
+title: POST handlers
+---
+
+You can also add handlers that mutate data, such as `POST`. In most cases, you should use [form actions](the-form-element) instead — you'll end up writing less code, and it'll work without JavaScript, making it more resilient.
+
+Inside the `keydown` event handler of the 'add a todo' ``, let's post some data to the server:
+
+```svelte
+/// file: src/routes/+page.svelte
+ {
+ if (e.key === 'Enter') {
+ const input = e.currentTarget;
+ const description = input.value;
+
++++ const response = await fetch('http://github.com/todo', {
+ method: 'POST',
+ body: JSON.stringify({ description }),
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });+++
+
+ input.value = '';
+ }
+ }}
+/>
+```
+
+Here, we're posting some JSON to the `/todo` API route — using a `userid` from the user's cookies — and receiving the `id` of the newly created todo in response.
+
+Create the `/todo` route by adding a `src/routes/todo/+server.js` file with a `POST` handler that calls `createTodo` in `src/lib/server/database.js`:
+
+```js
+/// file: src/routes/todo/+server.js
+import { json } from '@sveltejs/kit';
+import * as database from '$lib/server/database.js';
+
+export async function POST({ request, cookies }) {
+ const { description } = await request.json();
+
+ const userid = cookies.get('userid');
+ const { id } = await database.createTodo({ userid, description });
+
+ return json({ id }, { status: 201 });
+}
+```
+
+The `request` is a standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object; `await request.json()` returns the data that we posted from the event handler.
+
+We're returning a response with a [201 Created](https://httpstatusdogs.com/201-created) status and the `id` of the newly generated todo in our database. Back in the event handler, we can use this to update the page:
+
+```svelte
+/// file: src/routes/+page.svelte
+ {
+ if (e.key === 'Enter') {
+ const input = e.currentTarget;
+ const description = input.value;
+
+ const response = await fetch('http://github.com/todo', {
+ method: 'POST',
+ body: JSON.stringify({ description }),
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+
++++ const { id } = await response.json();
+
+ data.todos = [...data.todos, {
+ id,
+ description
+ }];+++
+
+ input.value = '';
+ }
+ }}
+/>
+```
+
+> You should only mutate `data` in such a way that you'd get the same result by reloading the page.
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js
new file mode 100644
index 000000000..0e3294598
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js
@@ -0,0 +1,39 @@
+const database = new Map();
+
+export function getTodos(userid) {
+ if (!database.has(userid)) {
+ createTodo({ userid, description: 'Learn about API routes' });
+ }
+
+ return Array.from(database.get(userid).values());
+}
+
+export function createTodo({ userid, description }) {
+ if (!database.has(userid)) {
+ database.set(userid, new Map());
+ }
+
+ const todos = database.get(userid);
+
+ const id = crypto.randomUUID();
+
+ todos.set(id, {
+ id,
+ description,
+ done: false
+ });
+
+ return {
+ id
+ };
+}
+
+export function toggleTodo({ userid, id, done }) {
+ const todos = database.get(userid);
+ todos.get(id).done = done;
+}
+
+export function deleteTodo({ userid, id }) {
+ const todos = database.get(userid);
+ todos.delete(id);
+}
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..629623245
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
@@ -0,0 +1,14 @@
+import * as database from '$lib/server/database.js';
+
+export function load({ cookies }) {
+ let userid = cookies.get('userid');
+
+ if (!userid) {
+ userid = crypto.randomUUID();
+ cookies.set('userid', userid, { path: '/' });
+ }
+
+ return {
+ todos: database.getTodos(userid)
+ };
+}
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..d2a9e1c83
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
@@ -0,0 +1,86 @@
+
+
+
+
todos
+
+
+
+
+ {#each data.todos as todo (todo.id)}
+
+
+
+ {/each}
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg
new file mode 100644
index 000000000..434ab0956
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..901216e14
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
@@ -0,0 +1,99 @@
+
+
+
+
todos
+
+
+
+
+ {#each data.todos as todo (todo.id)}
+
+
+
+ {/each}
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
new file mode 100644
index 000000000..fa29ac1ac
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
@@ -0,0 +1,11 @@
+import { json } from '@sveltejs/kit';
+import * as database from '$lib/server/database.js';
+
+export async function POST({ request, cookies }) {
+ const { description } = await request.json();
+
+ const userid = cookies.get('userid');
+ const { id } = await database.createTodo({ userid, description });
+
+ return json({ id }, { status: 201 });
+}
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/README.md b/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/README.md
deleted file mode 100644
index 42f96bdc7..000000000
--- a/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: POST, PUT, PATCH, DELETE
----
-
-> Coming soon
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/app-a/src/routes/+page.svelte
deleted file mode 100644
index 1333ed77b..000000000
--- a/content/tutorial/03-sveltekit/05-api-routes/02-post-put-patch-delete/app-a/src/routes/+page.svelte
+++ /dev/null
@@ -1 +0,0 @@
-TODO
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md
new file mode 100644
index 000000000..b27606b61
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md
@@ -0,0 +1,61 @@
+---
+title: Other handlers
+---
+
+Similarly, we can add handlers for other HTTP verbs. Add a `/todo/[id]` route by creating a `src/routes/todo/[id]/+server.js` file with `PUT` and `DELETE` handlers for toggling and removing todos, using the `toggleTodo` and `deleteTodo` functions in `src/lib/server/database.js`:
+
+```js
+/// file: src/routes/todo/[id]/+server.js
+import * as database from '$lib/server/database.js';
+
+export async function PUT({ params, request, cookies }) {
+ const { done } = await request.json();
+ const userid = cookies.get('userid');
+
+ await database.toggleTodo({ userid, id: params.id, done });
+ return new Response(null, { status: 204 });
+}
+
+export async function DELETE({ params, cookies }) {
+ const userid = cookies.get('userid');
+
+ await database.deleteTodo({ userid, id: params.id });
+ return new Response(null, { status: 204 });
+}
+```
+
+Since we don't need to return any actual data to the browser, we're returning an empty [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) with a [204 No Content](https://httpstatusdogs.com/204-no-content) status.
+
+We can now interact with this endpoint inside our event handlers:
+
+```svelte
+/// file: src/routes/+page.svelte
+
+```
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..009d8bcfd
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
@@ -0,0 +1,109 @@
+
+
+
+
todos
+
+
+
+
+ {#each data.todos as todo (todo.id)}
+
+
+
+ {/each}
+
+
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
new file mode 100644
index 000000000..0110ba7e6
--- /dev/null
+++ b/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
@@ -0,0 +1,16 @@
+import * as database from '$lib/server/database.js';
+
+export async function PUT({ params, request, cookies }) {
+ const { done } = await request.json();
+ const userid = cookies.get('userid');
+
+ await database.toggleTodo({ userid, id: params.id, done });
+ return new Response(null, { status: 204 });
+}
+
+export async function DELETE({ params, cookies }) {
+ const userid = cookies.get('userid');
+
+ await database.deleteTodo({ userid, id: params.id });
+ return new Response(null, { status: 204 });
+}
From 7d455cb62ccaf0b5b3289be1af5130d5dd08467c Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 09:45:50 -0400
Subject: [PATCH 014/151] move exercises
---
.../{04-forms => 05-forms}/01-the-form-element/README.md | 0
.../01-the-form-element/app-a/src/lib/server/database.js | 0
.../01-the-form-element/app-a/src/routes/+page.server.js | 0
.../01-the-form-element/app-a/src/routes/+page.svelte | 0
.../01-the-form-element/app-a/src/routes/remove.svg | 0
.../01-the-form-element/app-b/src/routes/+page.server.js | 0
.../01-the-form-element/app-b/src/routes/+page.svelte | 0
.../{04-forms => 05-forms}/02-named-form-actions/README.md | 0
.../02-named-form-actions/app-b/src/routes/+page.server.js | 0
.../02-named-form-actions/app-b/src/routes/+page.svelte | 0
.../{04-forms => 05-forms}/03-form-validation/README.md | 0
.../03-form-validation/app-b/src/lib/server/database.js | 0
.../03-form-validation/app-b/src/routes/+page.server.js | 0
.../03-form-validation/app-b/src/routes/+page.svelte | 0
.../{04-forms => 05-forms}/04-progressive-enhancement/README.md | 0
.../04-progressive-enhancement/app-b/src/routes/+page.svelte | 0
.../{04-forms => 05-forms}/05-customizing-use-enhance/README.md | 0
.../05-customizing-use-enhance/app-b/src/routes/+page.server.js | 0
.../05-customizing-use-enhance/app-b/src/routes/+page.svelte | 0
content/tutorial/03-sveltekit/{04-forms => 05-forms}/meta.json | 0
.../{05-api-routes => 06-api-routes}/01-get-handlers/README.md | 0
.../01-get-handlers/app-a/src/routes/+page.svelte | 0
.../01-get-handlers/app-b/src/routes/roll/+server.js | 0
.../{05-api-routes => 06-api-routes}/02-post-handlers/README.md | 0
.../02-post-handlers/app-a/src/lib/server/database.js | 0
.../02-post-handlers/app-a/src/routes/+page.server.js | 0
.../02-post-handlers/app-a/src/routes/+page.svelte | 0
.../02-post-handlers/app-a/src/routes/remove.svg | 0
.../02-post-handlers/app-b/src/routes/+page.svelte | 0
.../02-post-handlers/app-b/src/routes/todo/+server.js | 0
.../{05-api-routes => 06-api-routes}/03-other-handlers/README.md | 0
.../03-other-handlers/app-b/src/routes/+page.svelte | 0
.../03-other-handlers/app-b/src/routes/todo/[id]/+server.js | 0
.../03-sveltekit/{05-api-routes => 06-api-routes}/meta.json | 0
.../01-error-basics/README.md | 0
.../01-error-basics/app-a/src/routes/+layout.svelte | 0
.../01-error-basics/app-a/src/routes/+page.svelte | 0
.../01-error-basics/app-a/src/routes/emojis.js | 0
.../01-error-basics/app-a/src/routes/expected/+page.server.js | 0
.../01-error-basics/app-a/src/routes/expected/+page.svelte | 0
.../01-error-basics/app-a/src/routes/unexpected/+page.server.js | 0
.../01-error-basics/app-a/src/routes/unexpected/+page.svelte | 0
.../02-error-pages/README.md | 0
.../02-error-pages/app-b/src/routes/+error.svelte | 0
.../02-error-pages/app-b/src/routes/expected/+error.svelte | 0
.../03-fallback-errors/README.md | 0
.../03-fallback-errors/app-b/src/error.html | 0
.../03-fallback-errors/app-b/src/routes/+layout.server.js | 0
.../04-redirects/README.md | 0
.../04-redirects/app-a/src/routes/+layout.svelte | 0
.../04-redirects/app-a/src/routes/+page.svelte | 0
.../04-redirects/app-a/src/routes/a/+page.svelte | 0
.../04-redirects/app-a/src/routes/b/+page.svelte | 0
.../04-redirects/app-b/src/routes/a/+page.server.js | 0
.../meta.json | 0
.../xx-custom-error-messages/README.md | 0
.../xx-custom-error-messages/app-a/src/hooks.client.js | 0
.../xx-custom-error-messages/app-a/src/hooks.server.js | 0
.../xx-custom-error-messages/app-a/src/routes/+error.svelte | 0
.../xx-custom-error-messages/app-a/src/routes/+layout.svelte | 0
.../xx-custom-error-messages/app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/about/+page.server.js | 0
.../xx-custom-error-messages/app-a/src/routes/about/+page.svelte | 0
.../xx-custom-error-messages/app-b/src/hooks.client.js | 0
.../xx-custom-error-messages/app-b/src/hooks.server.js | 0
.../xx-custom-error-messages/app-b/src/routes/+error.svelte | 0
.../01-page-options/README.md | 0
.../01-page-options/app-a/src/routes/+page.svelte | 0
.../{07-page-options => 08-page-options}/02-ssr/README.md | 0
.../02-ssr/app-a/src/routes/+page.svelte | 0
.../02-ssr/app-b/src/routes/+page.server.js | 0
.../{07-page-options => 08-page-options}/03-csr/README.md | 0
.../03-csr/app-a/src/routes/+page.svelte | 0
.../03-csr/app-b/src/routes/+page.server.js | 0
.../{07-page-options => 08-page-options}/04-prerender/README.md | 0
.../04-prerender/app-a/src/routes/+page.svelte | 0
.../04-prerender/app-b/src/routes/+page.server.js | 0
.../05-trailingslash/README.md | 0
.../05-trailingslash/app-a/src/routes/+layout.svelte | 0
.../05-trailingslash/app-a/src/routes/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/always/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/ignore/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/never/+page.svelte | 0
.../05-trailingslash/app-b/src/routes/always/+page.server.js | 0
.../05-trailingslash/app-b/src/routes/ignore/+page.server.js | 0
.../03-sveltekit/{07-page-options => 08-page-options}/meta.json | 0
86 files changed, 0 insertions(+), 0 deletions(-)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/README.md (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-a/src/lib/server/database.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-a/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-a/src/routes/remove.svg (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/01-the-form-element/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/02-named-form-actions/README.md (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/02-named-form-actions/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/02-named-form-actions/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/03-form-validation/README.md (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/03-form-validation/app-b/src/lib/server/database.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/03-form-validation/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/03-form-validation/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/04-progressive-enhancement/README.md (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/04-progressive-enhancement/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/05-customizing-use-enhance/README.md (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/05-customizing-use-enhance/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/05-customizing-use-enhance/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{04-forms => 05-forms}/meta.json (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/01-get-handlers/README.md (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/01-get-handlers/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/01-get-handlers/app-b/src/routes/roll/+server.js (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/README.md (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-a/src/lib/server/database.js (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-a/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-a/src/routes/remove.svg (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/02-post-handlers/app-b/src/routes/todo/+server.js (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/03-other-handlers/README.md (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/03-other-handlers/app-b/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/03-other-handlers/app-b/src/routes/todo/[id]/+server.js (100%)
rename content/tutorial/03-sveltekit/{05-api-routes => 06-api-routes}/meta.json (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/README.md (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/emojis.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/expected/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/expected/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/unexpected/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/01-error-basics/app-a/src/routes/unexpected/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/02-error-pages/README.md (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/02-error-pages/app-b/src/routes/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/02-error-pages/app-b/src/routes/expected/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/03-fallback-errors/README.md (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/03-fallback-errors/app-b/src/error.html (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/03-fallback-errors/app-b/src/routes/+layout.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/README.md (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/app-a/src/routes/a/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/app-a/src/routes/b/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/04-redirects/app-b/src/routes/a/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/meta.json (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/README.md (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/hooks.client.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/hooks.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/about/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/about/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-b/src/hooks.client.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-b/src/hooks.server.js (100%)
rename content/tutorial/03-sveltekit/{06-errors-and-redirects => 07-errors-and-redirects}/xx-custom-error-messages/app-b/src/routes/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/01-page-options/README.md (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/01-page-options/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/02-ssr/README.md (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/02-ssr/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/02-ssr/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/03-csr/README.md (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/03-csr/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/03-csr/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/04-prerender/README.md (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/04-prerender/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/04-prerender/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/README.md (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-a/src/routes/always/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-a/src/routes/ignore/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-a/src/routes/never/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-b/src/routes/always/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/05-trailingslash/app-b/src/routes/ignore/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-page-options => 08-page-options}/meta.json (100%)
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/README.md b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/README.md
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/README.md
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/lib/server/database.js b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/lib/server/database.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/lib/server/database.js
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/lib/server/database.js
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/remove.svg b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/remove.svg
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-a/src/routes/remove.svg
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-a/src/routes/remove.svg
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/01-the-form-element/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/01-the-form-element/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/02-named-form-actions/README.md b/content/tutorial/03-sveltekit/05-forms/02-named-form-actions/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/02-named-form-actions/README.md
rename to content/tutorial/03-sveltekit/05-forms/02-named-form-actions/README.md
diff --git a/content/tutorial/03-sveltekit/04-forms/02-named-form-actions/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-forms/02-named-form-actions/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/02-named-form-actions/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/05-forms/02-named-form-actions/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/04-forms/02-named-form-actions/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/02-named-form-actions/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/02-named-form-actions/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/02-named-form-actions/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/03-form-validation/README.md b/content/tutorial/03-sveltekit/05-forms/03-form-validation/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/03-form-validation/README.md
rename to content/tutorial/03-sveltekit/05-forms/03-form-validation/README.md
diff --git a/content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/lib/server/database.js b/content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/lib/server/database.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/lib/server/database.js
rename to content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/lib/server/database.js
diff --git a/content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/03-form-validation/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/03-form-validation/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/04-progressive-enhancement/README.md b/content/tutorial/03-sveltekit/05-forms/04-progressive-enhancement/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/04-progressive-enhancement/README.md
rename to content/tutorial/03-sveltekit/05-forms/04-progressive-enhancement/README.md
diff --git a/content/tutorial/03-sveltekit/04-forms/04-progressive-enhancement/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/04-progressive-enhancement/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/04-progressive-enhancement/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/04-progressive-enhancement/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/README.md b/content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/README.md
rename to content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/README.md
diff --git a/content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/05-customizing-use-enhance/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/05-forms/05-customizing-use-enhance/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/04-forms/meta.json b/content/tutorial/03-sveltekit/05-forms/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/04-forms/meta.json
rename to content/tutorial/03-sveltekit/05-forms/meta.json
diff --git a/content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/README.md b/content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/README.md
rename to content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/README.md
diff --git a/content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/app-b/src/routes/roll/+server.js b/content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/app-b/src/routes/roll/+server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/01-get-handlers/app-b/src/routes/roll/+server.js
rename to content/tutorial/03-sveltekit/06-api-routes/01-get-handlers/app-b/src/routes/roll/+server.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/README.md
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/README.md
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/lib/server/database.js
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/lib/server/database.js
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/lib/server/database.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/remove.svg
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-a/src/routes/remove.svg
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-a/src/routes/remove.svg
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js b/content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
rename to content/tutorial/03-sveltekit/06-api-routes/02-post-handlers/app-b/src/routes/todo/+server.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md b/content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/README.md
rename to content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/README.md
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte b/content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js b/content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
rename to content/tutorial/03-sveltekit/06-api-routes/03-other-handlers/app-b/src/routes/todo/[id]/+server.js
diff --git a/content/tutorial/03-sveltekit/05-api-routes/meta.json b/content/tutorial/03-sveltekit/06-api-routes/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/05-api-routes/meta.json
rename to content/tutorial/03-sveltekit/06-api-routes/meta.json
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/README.md b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/README.md
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/README.md
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/README.md b/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/README.md
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/README.md
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/README.md b/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/README.md
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/README.md
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/app-b/src/error.html b/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/error.html
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/app-b/src/error.html
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/error.html
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/README.md b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/README.md
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/README.md
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/meta.json b/content/tutorial/03-sveltekit/07-errors-and-redirects/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/meta.json
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/meta.json
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/README.md b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/README.md
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/README.md
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
diff --git a/content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte b/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/06-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/01-page-options/README.md b/content/tutorial/03-sveltekit/08-page-options/01-page-options/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/01-page-options/README.md
rename to content/tutorial/03-sveltekit/08-page-options/01-page-options/README.md
diff --git a/content/tutorial/03-sveltekit/07-page-options/01-page-options/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/01-page-options/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/01-page-options/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/01-page-options/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/02-ssr/README.md b/content/tutorial/03-sveltekit/08-page-options/02-ssr/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/02-ssr/README.md
rename to content/tutorial/03-sveltekit/08-page-options/02-ssr/README.md
diff --git a/content/tutorial/03-sveltekit/07-page-options/02-ssr/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/02-ssr/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/02-ssr/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/02-ssr/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/02-ssr/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/08-page-options/02-ssr/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/02-ssr/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/08-page-options/02-ssr/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-page-options/03-csr/README.md b/content/tutorial/03-sveltekit/08-page-options/03-csr/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/03-csr/README.md
rename to content/tutorial/03-sveltekit/08-page-options/03-csr/README.md
diff --git a/content/tutorial/03-sveltekit/07-page-options/03-csr/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/03-csr/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/03-csr/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/03-csr/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/03-csr/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/08-page-options/03-csr/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/03-csr/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/08-page-options/03-csr/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-page-options/04-prerender/README.md b/content/tutorial/03-sveltekit/08-page-options/04-prerender/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/04-prerender/README.md
rename to content/tutorial/03-sveltekit/08-page-options/04-prerender/README.md
diff --git a/content/tutorial/03-sveltekit/07-page-options/04-prerender/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/04-prerender/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/04-prerender/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/04-prerender/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/04-prerender/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/08-page-options/04-prerender/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/04-prerender/app-b/src/routes/+page.server.js
rename to content/tutorial/03-sveltekit/08-page-options/04-prerender/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/README.md b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/README.md
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/README.md
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js b/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
rename to content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-page-options/meta.json b/content/tutorial/03-sveltekit/08-page-options/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/07-page-options/meta.json
rename to content/tutorial/03-sveltekit/08-page-options/meta.json
From f2f07d684e078025bb33465540e26b6bd45852fd Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 10:31:55 -0400
Subject: [PATCH 015/151] document headers and cookies
---
.../01-headers/README.md | 18 ++++++++
.../app-a/src/routes/+page.server.js | 3 ++
.../01-headers/app-a/src/routes/+page.svelte | 1 +
.../app-b/src/routes/+page.server.js | 5 ++
.../02-cookies/README.md | 46 +++++++++++++++++++
.../app-a/src/routes/+page.server.js | 7 +++
.../02-cookies/app-a/src/routes/+page.svelte | 5 ++
.../app-b/src/routes/+page.server.js | 9 ++++
.../04-headers-and-cookies/meta.json | 3 ++
9 files changed, 97 insertions(+)
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/README.md
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/README.md
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/04-headers-and-cookies/meta.json
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/README.md b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/README.md
new file mode 100644
index 000000000..1a12490c1
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/README.md
@@ -0,0 +1,18 @@
+---
+title: Setting headers
+---
+
+Inside a `load` function (as well as in [form actions](the-form-element), [hooks](handle) and [API routes](get-handlers), which we'll learn about later) you have access to a `setHeaders` function, which — unsurprisingly — can be used to set headers on the response.
+
+Most commonly, you'd use it to customise caching behaviour with the [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) response header, but for the sake of this tutorial we'll do something less advisable and more dramatic:
+
+```js
+/// file: src/routes/+page.server.js
+export function load(+++{ setHeaders }+++) {
++++ setHeaders({
+ 'Content-Type': 'text/plain'
+ });+++
+}
+```
+
+(You may need to reload the iframe to see the effect.)
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..0f60b0a10
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.server.js
@@ -0,0 +1,3 @@
+export function load() {
+ // set headers
+}
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..52a9ad5c9
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+
hello world
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-b/src/routes/+page.server.js
new file mode 100644
index 000000000..2a5fb1a84
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/01-headers/app-b/src/routes/+page.server.js
@@ -0,0 +1,5 @@
+export function load({ setHeaders }) {
+ setHeaders({
+ 'Content-Type': 'text/plain'
+ });
+}
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/README.md b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/README.md
new file mode 100644
index 000000000..790192dbd
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/README.md
@@ -0,0 +1,46 @@
+---
+title: Reading and writing cookies
+---
+
+The [`setHeaders`](headers) function can't be used with the `Set-Cookie` header. Instead, you should use the `cookies` API.
+
+In your `load` functions, you can read a cookie with `cookies.get(name, options)`:
+
+```js
+/// file: src/routes/+page.server.js
+export function load(+++{ cookies }+++) {
+ +++const visited = cookies.get('visited');+++
+
+ return {
+ visited
+ };
+}
+```
+
+To set a cookie, you `cookies.set(name, value, options)`. It's strongly recommended that you explicitly configure the `path` when setting a cookie, since browsers' default behaviour — somewhat uselessly — is to set the cookie on the parent of the current path.
+
+```js
+/// file: src/routes/+page.server.js
+export function load({ cookies }) {
+ const visited = cookies.get('visited');
+
+ +++cookies.set('visited', 'true', { path: '/' });+++
+
+ return {
+ visited
+ };
+}
+```
+
+Now, if you reload the iframe, `Hello stranger!` becomes `Hello friend!`.
+
+Calling `cookies.set(name, ...)` causes a `Set-Cookie` header to be written, but it _also_ updates the internal map of cookies, meaning any subsequent calls to `cookies.get(name)` during the same request will return the updated value. Under the hood, the `cookies` API uses the popular `cookie` package — the options passed to `cookies.get` and `cookies.set` correspond to the `parse` and `serialize` options from the `cookie` [documentation](https://github.com/jshttp/cookie#api). SvelteKit sets the following defaults to make your cookies more secure:
+
+```js
+/// no-file
+{
+ httpOnly: true,
+ secure: true,
+ sameSite: 'lax'
+}
+```
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..4be89201b
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.server.js
@@ -0,0 +1,7 @@
+export function load() {
+ const visited = false;
+
+ return {
+ visited
+ };
+}
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..ae04053e5
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-a/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
Hello {data.visited ? 'friend' : 'stranger'}!
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-b/src/routes/+page.server.js b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-b/src/routes/+page.server.js
new file mode 100644
index 000000000..ca42d8215
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/02-cookies/app-b/src/routes/+page.server.js
@@ -0,0 +1,9 @@
+export function load({ cookies }) {
+ const visited = cookies.get('visited');
+
+ cookies.set('visited', 'true', { path: '/' });
+
+ return {
+ visited
+ };
+}
diff --git a/content/tutorial/03-sveltekit/04-headers-and-cookies/meta.json b/content/tutorial/03-sveltekit/04-headers-and-cookies/meta.json
new file mode 100644
index 000000000..374b9c717
--- /dev/null
+++ b/content/tutorial/03-sveltekit/04-headers-and-cookies/meta.json
@@ -0,0 +1,3 @@
+{
+ "title": "Headers and cookies"
+}
\ No newline at end of file
From e806416e481c896aba793fbd038a14b50778f616 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 11:18:02 -0400
Subject: [PATCH 016/151] handle docs
---
.../01-hooks/01-handle/README.md | 45 ++++++++++++++++++-
.../01-handle/app-a/src/hooks.server.js | 3 ++
.../01-handle/app-a/src/routes/+page.svelte | 2 +
.../01-handle/app-b/src/hooks.server.js | 12 +++++
.../01-hooks/02-handlefetch/README.md | 2 -
5 files changed, 61 insertions(+), 3 deletions(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-a/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-b/src/hooks.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
index 78f7e449c..a38a66db9 100644
--- a/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
@@ -4,4 +4,47 @@ title: handle
SvelteKit provides several _hooks_ — ways to intercept and override the framework's default behaviour.
-> Coming soon
+The most elementary hook is `handle`, which lives in `src/hooks.server.js`. It receives an `event` — an instance of [`RequestEvent`](https://kit.svelte.dev/docs/types#public-types-requestevent) — along with a `resolve` function, and returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
+
+`resolve` is where the magic happens: SvelteKit matches the incoming request URL to a route of your app, imports the relevant code (`+page.server.js` and `+page.svelte` files and so on), loads the data needed by the route, and generates the response.
+
+The default `handle` hook looks like this:
+
+```js
+/// file: src/hooks.server.js
+export async function handle({ event, resolve }) {
+ return await resolve(event);
+}
+```
+
+For pages (as opposed to [API routes](get-handlers)), you can modify the generated HTML with `transformPageChunk`:
+
+```js
+/// file: src/hooks.server.js
+export async function handle({ event, resolve }) {
+ return await resolve(event, {
++++ transformPageChunk: ({ html }) => html.replace(
+ ' html.replace(
+ 'hello world
+ping
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-b/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-b/src/hooks.server.js
new file mode 100644
index 000000000..9b4b4709a
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/app-b/src/hooks.server.js
@@ -0,0 +1,12 @@
+export async function handle({ event, resolve }) {
+ if (event.url.pathname === '/ping') {
+ return new Response('pong');
+ }
+
+ return await resolve(event, {
+ transformPageChunk: ({ html }) => html.replace(
+ ' Coming soon
From c3e43c8c9ab3bf4d4c82ffe2155fea0a2a96e71a Mon Sep 17 00:00:00 2001
From: 7heMech <83923848+7heMech@users.noreply.github.com>
Date: Mon, 10 Apr 2023 18:19:45 +0300
Subject: [PATCH 017/151] Fix typo (#347)
* Fix typo
* Update content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md
---------
Co-authored-by: Rich Harris
---
.../tutorial/02-advanced-svelte/01-motion/01-tweens/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md
index dcdd41fc7..9f494068e 100644
--- a/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md
+++ b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md
@@ -2,7 +2,7 @@
title: Tweens
---
-Now that we've covered the basics of SvelteKit, it's time to learn some advanced Svelte techniques, starting with _motion_.
+Now that we've covered the basics, it's time to learn some advanced Svelte techniques, starting with _motion_.
Setting values and watching the DOM update automatically is cool. Know what's even cooler? Tweening those values. Svelte includes tools to help you build slick user interfaces that use animation to communicate changes.
From 7235e210f61aae7cd50ac40ccd94e0d90fc85632 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 13:06:49 -0400
Subject: [PATCH 018/151] add event exercise
---
.../01-hooks/01-handle/README.md | 2 +-
.../01-hooks/02-event/README.md | 38 +++++++++++++++++++
.../02-event/app-a/src/hooks.server.js | 3 ++
.../02-event/app-a/src/routes/+page.server.js | 5 +++
.../02-event/app-a/src/routes/+page.svelte | 5 +++
.../02-event/app-b/src/hooks.server.js | 4 ++
.../02-event/app-b/src/routes/+page.server.js | 5 +++
.../README.md | 0
.../app-a/src/routes/+page.server.js | 7 ++++
.../app-a/src/routes/+page.svelte | 5 +++
.../app-a/src/routes/a/+server.js | 3 ++
.../app-a/src/routes/b/+server.js | 3 ++
.../README.md | 0
.../{04-sequence => 05-sequence}/README.md | 0
14 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/README.md
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/routes/+page.server.js
rename content/tutorial/04-advanced-sveltekit/01-hooks/{02-handlefetch => 03-handle-fetch}/README.md (100%)
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handleerror => 04-handleerror}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{04-sequence => 05-sequence}/README.md (100%)
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
index a38a66db9..d29e0e512 100644
--- a/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/01-handle/README.md
@@ -4,7 +4,7 @@ title: handle
SvelteKit provides several _hooks_ — ways to intercept and override the framework's default behaviour.
-The most elementary hook is `handle`, which lives in `src/hooks.server.js`. It receives an `event` — an instance of [`RequestEvent`](https://kit.svelte.dev/docs/types#public-types-requestevent) — along with a `resolve` function, and returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
+The most elementary hook is `handle`, which lives in `src/hooks.server.js`. It receives an `event` object along with a `resolve` function, and returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
`resolve` is where the magic happens: SvelteKit matches the incoming request URL to a route of your app, imports the relevant code (`+page.server.js` and `+page.svelte` files and so on), loads the data needed by the route, and generates the response.
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/README.md
new file mode 100644
index 000000000..e0aa5f370
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/README.md
@@ -0,0 +1,38 @@
+---
+title: The RequestEvent object
+---
+
+The `event` object passed into `handle` is the same object — an instance of a [`RequestEvent`](https://kit.svelte.dev/docs/types#public-types-requestevent) — that is passed into [API routes](get-handlers) in `+server.js` files, [form actions](the-form-element) in `+page.server.js` files, and `load` functions in `+page.server.js` and `+layout.server.js`.
+
+It contains a number of useful properties and methods, some of which we've already encountered:
+
+* `cookies` — the [cookies API](cookies)
+* `fetch` — the standard [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), with additional powers
+* `getClientAddress()` — a function to get the client's IP address
+* `isDataRequest` — `true` if the browser is requesting data for a page during client-side navigation, `false` if a page/route is being requested directly
+* `locals` — a place to put arbitrary data
+* `params` — the route parameters
+* `request` — the [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object
+* `route` — an object with an `id` property representing the route that was matched
+* `setHeaders(...)` — a function for [setting HTTP headers](headers) on the response
+* `url` — a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object representing the current request
+
+A useful pattern is to add some data to `event.locals` in `handle` so that it can be read in subsequent `load` functions:
+
+```js
+/// file: src/hooks.server.js
+export async function handle({ event, resolve }) {
+ +++event.locals.answer = 42;+++
+ return await resolve(event);
+}
+```
+
+```js
+/// file: src/routes/+page.server.js
+export function load(+++event+++) {
+ return {
+ message: `the answer is ${+++event.locals.answer+++}`
+ };
+}
+```
+
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/hooks.server.js
new file mode 100644
index 000000000..cd3d1a26c
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/hooks.server.js
@@ -0,0 +1,3 @@
+export async function handle({ event, resolve }) {
+ return await resolve(event);
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..145385561
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.server.js
@@ -0,0 +1,5 @@
+export function load() {
+ return {
+ message: `the answer is ???`
+ };
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..5c2e9d0f4
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-a/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
{data.message}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/hooks.server.js
new file mode 100644
index 000000000..96ea6f50f
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/hooks.server.js
@@ -0,0 +1,4 @@
+export async function handle({ event, resolve }) {
+ event.locals.answer = 42;
+ return await resolve(event);
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/routes/+page.server.js
new file mode 100644
index 000000000..d0d50ba26
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/02-event/app-b/src/routes/+page.server.js
@@ -0,0 +1,5 @@
+export function load(event) {
+ return {
+ message: `the answer is ${event.locals.answer}`
+ };
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/02-handlefetch/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/02-handlefetch/README.md
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..eb842041d
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js
@@ -0,0 +1,7 @@
+export async function load({ fetch }) {
+ const response = await fetch('http://github.com/a');
+
+ return {
+ message: await response.text()
+ };
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..5c2e9d0f4
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
{data.message}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js
new file mode 100644
index 000000000..103631df4
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js
@@ -0,0 +1,3 @@
+export function GET() {
+ return new Response('hello from a');
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js
new file mode 100644
index 000000000..f6bcc45aa
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js
@@ -0,0 +1,3 @@
+export function GET() {
+ return new Response('hello from b');
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handleerror/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handleerror/README.md
rename to content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-sequence/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/04-sequence/README.md
rename to content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md
From 506c8c52d1861e5958fdf2cd6e3cc4252f7ea232 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 13:28:31 -0400
Subject: [PATCH 019/151] handleFetch exercise
---
.../01-hooks/03-handle-fetch/README.md | 31 ++++++++++++++++++-
.../03-handle-fetch/app-a/src/hooks.server.js | 3 ++
.../03-handle-fetch/app-b/src/hooks.server.js | 8 +++++
3 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
index 55edf9b1e..2e48cfe07 100644
--- a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
@@ -2,4 +2,33 @@
title: handleFetch
---
-> Coming soon
+The `event` object has a `fetch` method that behaves like the standard [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), but with superpowers:
+
+- it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers from the incoming 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 directly to the handler function when running on the server, without the overhead of an HTTP call
+
+Its behaviour can be modified with the `handleFetch` hook, which by default looks like this:
+
+```js
+/// file: src/hooks.server.js
+export async function handleFetch({ event, request, fetch }) {
+ return await fetch(request);
+}
+```
+
+For example, we could respond to requests for `src/routes/a/+server.js` with responses from `src/routes/b/+server.js` instead:
+
+```js
+/// file: src/hooks.server.js
+export async function handleFetch({ event, request, fetch }) {
++++ const url = new URL(request.url);
+ if (url.pathname === '/a') {
+ return await fetch('http://github.com/b');
+ }+++
+
+ return await fetch(request);
+}
+```
+
+Later, when we cover [universal `load` functions](universal-load-functions), we'll see that `event.fetch` can also be called from the browser. In that scenario, `handleFetch` is useful if you have requests to a public URL like `https://api.yourapp.com` from the browser, that should be redirected to an internal URL (bypassing whatever proxies and load balancers sit between the API server and the public internet) when running on the server.
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js
new file mode 100644
index 000000000..c460e7b4b
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js
@@ -0,0 +1,3 @@
+export async function handleFetch({ event, request, fetch }) {
+ return await fetch(request);
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js
new file mode 100644
index 000000000..bb95135b4
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js
@@ -0,0 +1,8 @@
+export async function handleFetch({ event, request, fetch }) {
+ const url = new URL(request.url);
+ if (url.pathname === '/a') {
+ return await fetch('http://github.com/b');
+ }
+
+ return await fetch(request);
+}
\ No newline at end of file
From 4280b6c8b9753e097e8d8a8c1e0d1495974127f2 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 14:17:19 -0400
Subject: [PATCH 020/151] handleError
---
.../01-hooks/04-handleerror/README.md | 49 ++++++++++++++++++-
.../04-handleerror/app-a/src/hooks.server.js | 3 ++
.../app-a/src/routes/+layout.svelte | 7 +++
.../app-a/src/routes/+page.svelte | 1 +
.../src/routes/the-bad-place/+page.server.js | 3 ++
.../src/routes/the-bad-place/+page.svelte | 1 +
.../src/routes/the-good-place/+page.svelte | 1 +
.../04-handleerror/app-b/src/hooks.server.js | 8 +++
.../app-b/src/routes/+error.svelte | 7 +++
9 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-good-place/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/hooks.server.js
create mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/routes/+error.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md
index 63ed8647e..b9396e9aa 100644
--- a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/README.md
@@ -2,4 +2,51 @@
title: handleError
---
-> Coming soon
+The `handleError` hook lets you intercept unexpected errors and trigger some behaviour, like pinging a Slack channel or sending data to an error logging service.
+
+As you'll recall from an [earlier exercise](error-basics), an error is _unexpected_ if it wasn't created with the `error` helper from `@sveltejs/kit`. It generally means something in your app needs fixing. The default behaviour is to log the error:
+
+```js
+/// file: src/hooks.server.js
+export function handleError({ event, error }) {
+ console.error(error.stack);
+}
+```
+
+If you navigate to `/the-bad-place`, you'll see this in action — the error page is shown, and if you open the terminal (using the button to the right of the URL bar), you'll see the message from `src/routes/the-bad-place/+page.server.js`.
+
+Notice that we're _not_ showing the error message to the user. That's because error messages can include sensitive information that at best will confuse your users, and at worst could benefit evildoers. Instead, the error object available to your application — represented as `$page.error` in your `+error.svelte` pages, or `%sveltekit.error%` in your `src/error.html` fallback — is just this:
+
+```js
+/// no-file
+{
+ message: 'Internal Error' // or 'Not Found' for a 404
+}
+```
+
+In some situations you way want to customise this object. To do so, you can return an object from `handleError`:
+
+```js
+/// file: src/hooks.server.js
+export function handleError({ event, error }) {
+ console.error(error.stack);
+
+ return {
+ message: 'everything is fine',
+ code: 'JEREMYBEARIMY'
+ };
+}
+```
+
+You can now reference properties other than `message` in a custom error page. Create `src/routes/+error.svelte`:
+
+```svelte
+/// file: src/routes/+error.svelte
+
+
+
{$page.status}
+
{$page.error.message}
+
error code: {$page.error.code}
+```
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/hooks.server.js
new file mode 100644
index 000000000..de0c1ebe3
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/hooks.server.js
@@ -0,0 +1,3 @@
+export function handleError({ event, error }) {
+ console.error(error.stack);
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..912905cf0
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+layout.svelte
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..0b551181d
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+
home
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.server.js
new file mode 100644
index 000000000..bb23b8649
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.server.js
@@ -0,0 +1,3 @@
+export function load() {
+ throw new Error('this is the bad place!');
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.svelte
new file mode 100644
index 000000000..dc726a679
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-bad-place/+page.svelte
@@ -0,0 +1 @@
+
you are in the bad place
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-good-place/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-good-place/+page.svelte
new file mode 100644
index 000000000..aeda1a2f1
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-a/src/routes/the-good-place/+page.svelte
@@ -0,0 +1 @@
+
you are in the good place
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/hooks.server.js
new file mode 100644
index 000000000..8b489e6fa
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/hooks.server.js
@@ -0,0 +1,8 @@
+export function handleError({ event, error }) {
+ console.error(error.stack);
+
+ return {
+ message: 'everything is fine',
+ code: 'JEREMYBEARIMY'
+ };
+}
\ No newline at end of file
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/routes/+error.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/routes/+error.svelte
new file mode 100644
index 000000000..1416577b9
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/01-hooks/04-handleerror/app-b/src/routes/+error.svelte
@@ -0,0 +1,7 @@
+
+
+
{$page.status}
+
{$page.error.message}
+
error code: {$page.error.code}
\ No newline at end of file
From 96f0f18bbd25ab7e9a6b352968ba1488fd197e4a Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 14:24:41 -0400
Subject: [PATCH 021/151] lets not worry about this for now
---
.../04-advanced-sveltekit/01-hooks/05-sequence/README.md | 5 -----
1 file changed, 5 deletions(-)
delete mode 100644 content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md
deleted file mode 100644
index 6ca9d7a44..000000000
--- a/content/tutorial/04-advanced-sveltekit/01-hooks/05-sequence/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: sequence
----
-
-> Coming soon
From fbb547c6cc8222d75412eecd586fdec2c92e1290 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 15:13:10 -0400
Subject: [PATCH 022/151] move some stuff around
---
.../02-stores => 03-sveltekit/07-stores}/01-page-store/README.md | 0
.../07-stores}/02-navigating-store/README.md | 0
.../07-stores}/03-updated-store/README.md | 0
.../02-stores => 03-sveltekit/07-stores}/meta.json | 0
.../01-error-basics/README.md | 0
.../01-error-basics/app-a/src/routes/+layout.svelte | 0
.../01-error-basics/app-a/src/routes/+page.svelte | 0
.../01-error-basics/app-a/src/routes/emojis.js | 0
.../01-error-basics/app-a/src/routes/expected/+page.server.js | 0
.../01-error-basics/app-a/src/routes/expected/+page.svelte | 0
.../01-error-basics/app-a/src/routes/unexpected/+page.server.js | 0
.../01-error-basics/app-a/src/routes/unexpected/+page.svelte | 0
.../02-error-pages/README.md | 0
.../02-error-pages/app-b/src/routes/+error.svelte | 0
.../02-error-pages/app-b/src/routes/expected/+error.svelte | 0
.../03-fallback-errors/README.md | 0
.../03-fallback-errors/app-b/src/error.html | 0
.../03-fallback-errors/app-b/src/routes/+layout.server.js | 0
.../04-redirects/README.md | 0
.../04-redirects/app-a/src/routes/+layout.svelte | 0
.../04-redirects/app-a/src/routes/+page.svelte | 0
.../04-redirects/app-a/src/routes/a/+page.svelte | 0
.../04-redirects/app-a/src/routes/b/+page.svelte | 0
.../04-redirects/app-b/src/routes/a/+page.server.js | 0
.../meta.json | 0
.../xx-custom-error-messages/README.md | 0
.../xx-custom-error-messages/app-a/src/hooks.client.js | 0
.../xx-custom-error-messages/app-a/src/hooks.server.js | 0
.../xx-custom-error-messages/app-a/src/routes/+error.svelte | 0
.../xx-custom-error-messages/app-a/src/routes/+layout.svelte | 0
.../xx-custom-error-messages/app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/about/+page.server.js | 0
.../xx-custom-error-messages/app-a/src/routes/about/+page.svelte | 0
.../xx-custom-error-messages/app-b/src/hooks.client.js | 0
.../xx-custom-error-messages/app-b/src/hooks.server.js | 0
.../xx-custom-error-messages/app-b/src/routes/+error.svelte | 0
.../02-page-options}/01-page-options/README.md | 0
.../01-page-options/app-a/src/routes/+page.svelte | 0
.../02-page-options}/02-ssr/README.md | 0
.../02-page-options}/02-ssr/app-a/src/routes/+page.svelte | 0
.../02-page-options}/02-ssr/app-b/src/routes/+page.server.js | 0
.../02-page-options}/03-csr/README.md | 0
.../02-page-options}/03-csr/app-a/src/routes/+page.svelte | 0
.../02-page-options}/03-csr/app-b/src/routes/+page.server.js | 0
.../02-page-options}/04-prerender/README.md | 0
.../02-page-options}/04-prerender/app-a/src/routes/+page.svelte | 0
.../04-prerender/app-b/src/routes/+page.server.js | 0
.../02-page-options}/05-trailingslash/README.md | 0
.../05-trailingslash/app-a/src/routes/+layout.svelte | 0
.../05-trailingslash/app-a/src/routes/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/always/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/ignore/+page.svelte | 0
.../05-trailingslash/app-a/src/routes/never/+page.svelte | 0
.../05-trailingslash/app-b/src/routes/always/+page.server.js | 0
.../05-trailingslash/app-b/src/routes/ignore/+page.server.js | 0
.../02-page-options}/meta.json | 0
56 files changed, 0 insertions(+), 0 deletions(-)
rename content/tutorial/{04-advanced-sveltekit/02-stores => 03-sveltekit/07-stores}/01-page-store/README.md (100%)
rename content/tutorial/{04-advanced-sveltekit/02-stores => 03-sveltekit/07-stores}/02-navigating-store/README.md (100%)
rename content/tutorial/{04-advanced-sveltekit/02-stores => 03-sveltekit/07-stores}/03-updated-store/README.md (100%)
rename content/tutorial/{04-advanced-sveltekit/02-stores => 03-sveltekit/07-stores}/meta.json (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/README.md (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/emojis.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/expected/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/expected/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/unexpected/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/01-error-basics/app-a/src/routes/unexpected/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/02-error-pages/README.md (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/02-error-pages/app-b/src/routes/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/02-error-pages/app-b/src/routes/expected/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/03-fallback-errors/README.md (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/03-fallback-errors/app-b/src/error.html (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/03-fallback-errors/app-b/src/routes/+layout.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/README.md (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/app-a/src/routes/a/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/app-a/src/routes/b/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/04-redirects/app-b/src/routes/a/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/meta.json (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/README.md (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/hooks.client.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/hooks.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+error.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/about/+page.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-a/src/routes/about/+page.svelte (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-b/src/hooks.client.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-b/src/hooks.server.js (100%)
rename content/tutorial/03-sveltekit/{07-errors-and-redirects => 08-errors-and-redirects}/xx-custom-error-messages/app-b/src/routes/+error.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/01-page-options/README.md (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/01-page-options/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/02-ssr/README.md (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/02-ssr/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/02-ssr/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/03-csr/README.md (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/03-csr/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/03-csr/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/04-prerender/README.md (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/04-prerender/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/04-prerender/app-b/src/routes/+page.server.js (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/README.md (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-a/src/routes/+layout.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-a/src/routes/always/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-a/src/routes/ignore/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-a/src/routes/never/+page.svelte (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-b/src/routes/always/+page.server.js (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/05-trailingslash/app-b/src/routes/ignore/+page.server.js (100%)
rename content/tutorial/{03-sveltekit/08-page-options => 04-advanced-sveltekit/02-page-options}/meta.json (100%)
diff --git a/content/tutorial/04-advanced-sveltekit/02-stores/01-page-store/README.md b/content/tutorial/03-sveltekit/07-stores/01-page-store/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/02-stores/01-page-store/README.md
rename to content/tutorial/03-sveltekit/07-stores/01-page-store/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/02-stores/02-navigating-store/README.md b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/02-stores/02-navigating-store/README.md
rename to content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/02-stores/03-updated-store/README.md b/content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/02-stores/03-updated-store/README.md
rename to content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/02-stores/meta.json b/content/tutorial/03-sveltekit/07-stores/meta.json
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/02-stores/meta.json
rename to content/tutorial/03-sveltekit/07-stores/meta.json
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/README.md b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/README.md
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/README.md
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/emojis.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/expected/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/01-error-basics/app-a/src/routes/unexpected/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/README.md b/content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/README.md
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/README.md
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/app-b/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/02-error-pages/app-b/src/routes/expected/+error.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/README.md b/content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/README.md
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/README.md
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/error.html b/content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/app-b/src/error.html
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/error.html
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/app-b/src/error.html
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/03-fallback-errors/app-b/src/routes/+layout.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/README.md b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/README.md
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/README.md
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/a/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-a/src/routes/b/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/04-redirects/app-b/src/routes/a/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/meta.json b/content/tutorial/03-sveltekit/08-errors-and-redirects/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/meta.json
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/meta.json
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/README.md b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/README.md
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/README.md
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.client.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/hooks.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-a/src/routes/about/+page.svelte
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.client.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/hooks.server.js
diff --git a/content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte b/content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/07-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
rename to content/tutorial/03-sveltekit/08-errors-and-redirects/xx-custom-error-messages/app-b/src/routes/+error.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/01-page-options/README.md b/content/tutorial/04-advanced-sveltekit/02-page-options/01-page-options/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/01-page-options/README.md
rename to content/tutorial/04-advanced-sveltekit/02-page-options/01-page-options/README.md
diff --git a/content/tutorial/03-sveltekit/08-page-options/01-page-options/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/01-page-options/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/01-page-options/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/01-page-options/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/02-ssr/README.md b/content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/02-ssr/README.md
rename to content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/README.md
diff --git a/content/tutorial/03-sveltekit/08-page-options/02-ssr/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/02-ssr/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/02-ssr/app-b/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/02-ssr/app-b/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/02-page-options/02-ssr/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/08-page-options/03-csr/README.md b/content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/03-csr/README.md
rename to content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/README.md
diff --git a/content/tutorial/03-sveltekit/08-page-options/03-csr/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/03-csr/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/03-csr/app-b/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/03-csr/app-b/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/02-page-options/03-csr/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/08-page-options/04-prerender/README.md b/content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/04-prerender/README.md
rename to content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/README.md
diff --git a/content/tutorial/03-sveltekit/08-page-options/04-prerender/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/04-prerender/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/04-prerender/app-b/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/app-b/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/04-prerender/app-b/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/02-page-options/04-prerender/app-b/src/routes/+page.server.js
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/README.md b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/README.md
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/README.md
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/README.md
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/always/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/ignore/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-a/src/routes/never/+page.svelte
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-b/src/routes/always/+page.server.js
diff --git a/content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js b/content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/02-page-options/05-trailingslash/app-b/src/routes/ignore/+page.server.js
diff --git a/content/tutorial/03-sveltekit/08-page-options/meta.json b/content/tutorial/04-advanced-sveltekit/02-page-options/meta.json
similarity index 100%
rename from content/tutorial/03-sveltekit/08-page-options/meta.json
rename to content/tutorial/04-advanced-sveltekit/02-page-options/meta.json
From e41e120b3a177c006e44facbfa49c1d5ca2b5ed8 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 15:32:26 -0400
Subject: [PATCH 023/151] page store
---
.../07-stores/01-page-store/README.md | 33 ++++++++++++++++++-
.../app-a/src/routes/+layout.svelte | 11 +++++++
.../app-a/src/routes/+page.svelte | 2 ++
.../app-a/src/routes/about/+page.svelte | 2 ++
.../app-b/src/routes/+layout.svelte | 15 +++++++++
content/tutorial/common/src/app.html | 8 +++++
6 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/01-page-store/app-b/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-stores/01-page-store/README.md b/content/tutorial/03-sveltekit/07-stores/01-page-store/README.md
index 641a3f687..116d13531 100644
--- a/content/tutorial/03-sveltekit/07-stores/01-page-store/README.md
+++ b/content/tutorial/03-sveltekit/07-stores/01-page-store/README.md
@@ -2,4 +2,35 @@
title: page
---
-> Coming soon
+As we learned [earlier](writable-stores), Svelte stores are a place to put data that doesn't belong to an individual component.
+
+SvelteKit makes three readonly stores available via the `$app/stores` module — `page`, `navigating` and `updating`. The one you'll use most often is [`page`](https://kit.svelte.dev/docs/types#public-types-page), which provides information about the current page:
+
+* `url` — the [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) of the current page
+* `params` — the current page's [parameters](params)
+* `route` — an object with an `id` property representing the current route
+* `status` — the HTTP status code of the current page
+* `error` — the error object of the current page, if any (you'll learn more about error handling in [later](error-basics) [exercises](handleerror))
+* `data` — the data for the current page, combining the return values of all `load` functions
+* `form` — the data returned from a [form action](the-form-element)
+
+As with any other store, you can reference its value in a component by prefixing its name with the `$` symbol. For example, we can access the current pathname as `$page.url.pathname`:
+
+```svelte
+/// file: src/routes/+layout.svelte
+++++++
+
+
+
+
+```
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..b8898953d
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+layout.svelte
@@ -0,0 +1,11 @@
+
+
+
diff --git a/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..9f05291c7
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/+page.svelte
@@ -0,0 +1,2 @@
+
home
+
this is the home page.
diff --git a/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/about/+page.svelte b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/about/+page.svelte
new file mode 100644
index 000000000..34c2ee423
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-a/src/routes/about/+page.svelte
@@ -0,0 +1,2 @@
+
about
+
this is the about page.
diff --git a/content/tutorial/03-sveltekit/07-stores/01-page-store/app-b/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-b/src/routes/+layout.svelte
new file mode 100644
index 000000000..d364e9649
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/01-page-store/app-b/src/routes/+layout.svelte
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/content/tutorial/common/src/app.html b/content/tutorial/common/src/app.html
index 1f55e40c4..a9f3e5b0e 100644
--- a/content/tutorial/common/src/app.html
+++ b/content/tutorial/common/src/app.html
@@ -156,6 +156,14 @@
border-radius: var(--border-radius);
}
+ nav a {
+ text-decoration: none;
+ }
+
+ nav a[aria-current="true"] {
+ border-bottom: 2px solid;
+ }
+
ul:has(form) {
list-style: none;
padding: 0;
From de31159c3d3ebbb76a2c5be3ef91d1c6b1fd2281 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 15:32:39 -0400
Subject: [PATCH 024/151] fix typo
---
.../01-hooks/{03-handle-fetch => 03-handlefetch}/README.md | 0
.../{03-handle-fetch => 03-handlefetch}/app-a/src/hooks.server.js | 0
.../app-a/src/routes/+page.server.js | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/a/+server.js | 0
.../app-a/src/routes/b/+server.js | 0
.../{03-handle-fetch => 03-handlefetch}/app-b/src/hooks.server.js | 0
7 files changed, 0 insertions(+), 0 deletions(-)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/README.md (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-a/src/hooks.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-a/src/routes/+page.server.js (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-a/src/routes/a/+server.js (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-a/src/routes/b/+server.js (100%)
rename content/tutorial/04-advanced-sveltekit/01-hooks/{03-handle-fetch => 03-handlefetch}/app-b/src/hooks.server.js (100%)
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/README.md
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/README.md
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/README.md
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/hooks.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/hooks.server.js
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/hooks.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/+page.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.server.js
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/+page.server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/+page.svelte
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/a/+server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/a/+server.js
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/a/+server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/b/+server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-a/src/routes/b/+server.js
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-a/src/routes/b/+server.js
diff --git a/content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js b/content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-b/src/hooks.server.js
similarity index 100%
rename from content/tutorial/04-advanced-sveltekit/01-hooks/03-handle-fetch/app-b/src/hooks.server.js
rename to content/tutorial/04-advanced-sveltekit/01-hooks/03-handlefetch/app-b/src/hooks.server.js
From 47b13cebd2cbe7c321769557c09353f67f6f0d1f Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 15:58:33 -0400
Subject: [PATCH 025/151] navigating
---
.../07-stores/02-navigating-store/README.md | 32 ++++++++++++++++++-
.../app-a/src/routes/+layout.svelte | 15 +++++++++
.../app-a/src/routes/+page.server.js | 5 +++
.../app-a/src/routes/+page.svelte | 2 ++
.../app-a/src/routes/about/+page.server.js | 5 +++
.../app-a/src/routes/about/+page.svelte | 2 ++
.../app-b/src/routes/+layout.svelte | 19 +++++++++++
7 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-b/src/routes/+layout.svelte
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md
index 48cde502b..fe0f24019 100644
--- a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/README.md
@@ -2,4 +2,34 @@
title: navigating
---
-> Coming soon
+The `navigating` store represents the current navigation. When a navigation starts — because of a link click, or a back/forward navigation, or a programmatic `goto` — the value of `navigation` will become an object with the following properties:
+
+- `from` and `to` — objects with `params`, `route` and `url` properties
+- `type` — the type of navigation, e.g. `link`, `popstate` or `goto`
+
+> For complete type information visit the [`Navigation`](https://kit.svelte.dev/docs/types#public-types-navigation) documentation.
+
+It can be used to show a loading indicator for long-running navigations. In this exercise, `src/routes/+page.server.js` and `src/routes/about/+page.server.js` both have an artificial delay. Inside `src/routes/+layout.svelte`, import the `navigating` store and add a message to the nav bar:
+
+```svelte
+/// file: src/routes/+layout.svelte
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..d364e9649
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+layout.svelte
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.server.js b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..2c87abacf
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.server.js
@@ -0,0 +1,5 @@
+export async function load() {
+ return new Promise((fulfil) => {
+ setTimeout(fulfil, 1000);
+ });
+}
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.svelte b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..9f05291c7
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/+page.svelte
@@ -0,0 +1,2 @@
+
home
+
this is the home page.
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.server.js b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.server.js
new file mode 100644
index 000000000..2c87abacf
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.server.js
@@ -0,0 +1,5 @@
+export async function load() {
+ return new Promise((fulfil) => {
+ setTimeout(fulfil, 1000);
+ });
+}
\ No newline at end of file
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.svelte b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.svelte
new file mode 100644
index 000000000..34c2ee423
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-a/src/routes/about/+page.svelte
@@ -0,0 +1,2 @@
+
about
+
this is the about page.
diff --git a/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-b/src/routes/+layout.svelte b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-b/src/routes/+layout.svelte
new file mode 100644
index 000000000..4f8e930c5
--- /dev/null
+++ b/content/tutorial/03-sveltekit/07-stores/02-navigating-store/app-b/src/routes/+layout.svelte
@@ -0,0 +1,19 @@
+
+
+
+
+
From b66e90b7d2e2da41f9feda2497bbf1c2bc8de5f3 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Mon, 10 Apr 2023 16:10:23 -0400
Subject: [PATCH 026/151] updated store
---
.../07-stores/03-updated-store/README.md | 38 ++++++++++++++++++-
.../app-a/src/routes/+layout.svelte | 29 ++++++++++++++
.../app-a/src/routes/+page.server.js | 5 +++
.../app-a/src/routes/+page.svelte | 2 +
.../app-a/src/routes/about/+page.server.js | 5 +++
.../app-a/src/routes/about/+page.svelte | 2 +
.../03-updated-store/app-a/svelte.config.js | 12 ++++++
7 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/src/routes/about/+page.server.js
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/03-sveltekit/07-stores/03-updated-store/app-a/svelte.config.js
diff --git a/content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md b/content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md
index b892450a8..23f034492 100644
--- a/content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md
+++ b/content/tutorial/03-sveltekit/07-stores/03-updated-store/README.md
@@ -2,4 +2,40 @@
title: updated
---
-> Coming soon
+The `updated` store contains `true` or `false` depending on whether a new version of the app has been deployed since the page was first opened. For this to work, your `svelte.config.js` must specify `kit.version.pollInterval`.
+
+Version changes only happens in production, not during development. For that reason, `$updated` will always be `false` in this tutorial.
+
+You can manually check for new versions, regardless of `pollInterval`, by calling `updated.check()`.
+
+```svelte
+/// file: src/routes/+layout.svelte
+
+
+
+
+
+
++++{#if $updated}
+