From c1db80f81d5bfed977fb39ffd3f1d072de635b04 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 17 Oct 2022 18:13:46 +0200
Subject: [PATCH 001/177] start of routing tutorial
---
.../02-routing/01-pages/README.md | 2 ++
.../02-routing/02-layouts/README.md | 32 +++++++++++++++++
.../app-a/src/routes/+layout.svelte | 1 +
.../02-layouts/app-a/src/routes/+page.svelte | 17 +++++++++
.../app-a/src/routes/about/+page.svelte | 17 +++++++++
.../app-b/src/routes/+layout.svelte | 15 ++++++++
.../02-layouts/app-b/src/routes/+page.svelte | 3 ++
.../app-b/src/routes/about/+page.svelte | 3 ++
.../02-routing/03-loading-data/README.md | 36 +++++++++++++++++++
.../03-loading-data/app-a/src/routes/+page.js | 0
.../app-a/src/routes/+page.svelte | 12 +++++++
.../app-a/src/routes/api/+server.js | 3 ++
.../03-loading-data/app-b/src/routes/+page.js | 4 +++
.../app-b/src/routes/+page.svelte | 5 +++
.../{02-endpoints => 10-endpoints}/README.md | 0
.../app-a/src/routes/+page.svelte | 0
.../app-a/src/routes/about/+page.svelte | 0
.../app-b/src/routes/about/+page.svelte | 0
18 files changed, 150 insertions(+)
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+layout.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/about/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.svelte
rename content/tutorial/02-sveltekit/02-routing/{02-endpoints => 10-endpoints}/README.md (100%)
rename content/tutorial/02-sveltekit/02-routing/{02-endpoints => 10-endpoints}/app-a/src/routes/+page.svelte (100%)
rename content/tutorial/02-sveltekit/02-routing/{02-endpoints => 10-endpoints}/app-a/src/routes/about/+page.svelte (100%)
rename content/tutorial/02-sveltekit/02-routing/{02-endpoints => 10-endpoints}/app-b/src/routes/about/+page.svelte (100%)
diff --git a/content/tutorial/02-sveltekit/02-routing/01-pages/README.md b/content/tutorial/02-sveltekit/02-routing/01-pages/README.md
index 57eae033f..b67fcdfe3 100644
--- a/content/tutorial/02-sveltekit/02-routing/01-pages/README.md
+++ b/content/tutorial/02-sveltekit/02-routing/01-pages/README.md
@@ -4,6 +4,8 @@ title: Pages
SvelteKit uses filesystem-based routing, which means that the _routes_ of your app — in other words, what the app should do when a user navigates to a particular URL — are defined by the directories in your codebase.
+The routes are located within `src/routes`. Every directory within which contains a `+page.svelte` file creates a route in your app.
+
In this app we have two routes — `src/routes/+page.svelte`, which maps to `/`, and `src/routes/about/+page.svelte`, which maps to `/about`. Clicking the `about` link will take you from the home page to the about page.
> Unlike traditional multi-page apps, navigating to `/about` updates the contents of the current page, like a single-page app. This gives us the best of both worlds — fast server-rendered startup, then instant navigation.
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
new file mode 100644
index 000000000..eaad27dfb
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
@@ -0,0 +1,32 @@
+---
+title: Layouts
+---
+
+Sections of your app often share a common UI. To not repeat that code, we can use layouts.
+
+In this app we have two routes — `src/routes/+page.svelte`, and `src/routes/about/+page.svelte`. Both contain the same header which enables us to navigate around.
+
+We can deduplicate this code by moving the common UI into a `+layout.svelte` file. All pages in the same folder or below this file will share that UI. The layout itself needs a `` at minimum to define where the content is projected.
+
+Let's move the duplicate content from `src/routes/+page.svelte` and `src/routes/about/+page.svelte` into `src/routes/+layout.svelte`:
+
+```svelte
++++
++++
+
++++
+
++++
+```
+
+> Layouts can also be nested
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..4fa864ce7
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+layout.svelte
@@ -0,0 +1 @@
+
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..e630d164a
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+page.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/about/+page.svelte
new file mode 100644
index 000000000..212bd68ff
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/about/+page.svelte
@@ -0,0 +1,3 @@
+
About
+
+
This is the about page.
diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md b/content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md
new file mode 100644
index 000000000..abdddd1ac
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md
@@ -0,0 +1,36 @@
+---
+title: Loading Data
+---
+
+So far, we have seen how to create pages and layouts with static UI data. Most of your apps need to load some kind of data however. You could do this with a regular `fetch` inside `onMount`. That doesn't work with server-side-rendering or prerendering though, and you'd have half-finished pages loading data only after they are rendered.
+
+SvelteKit provides a better way to do this through `load` functions.
+
+This `load` function can appear in several places. Let's start with the `load` function inside `+page.js`.
+
+This `load` function runs on the server when the user visits your page initially, and on the client for all further navigations - it's isomorphic. We call it a "shared `load` function". To harmonize the differences between client and server, use the `fetch` function passed to `load` to load data. The return type of the `load` function needs to be an object at the top level, below that everything is allowed. If we return a promise, it's awaited. The result is passed to the `data` prop inside `+page.svelte`, so we can access it through `export let data`.
+
+Let's move the call inside `src/routes/+page.svelte` into `+page.js`:
+
+```svelte
+
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
new file mode 100644
index 000000000..7194f94f7
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
@@ -0,0 +1,3 @@
+export function GET() {
+ return new Response('Hello from your API');
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.js
new file mode 100644
index 000000000..560f092f9
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.js
@@ -0,0 +1,4 @@
+export async function load({ fetch }) {
+ const greeting = await fetch('/api').then((r) => r.text());
+ return { greeting };
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..7416c4d70
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-b/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
{data.greeting}
diff --git a/content/tutorial/02-sveltekit/02-routing/02-endpoints/README.md b/content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md
similarity index 100%
rename from content/tutorial/02-sveltekit/02-routing/02-endpoints/README.md
rename to content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md
diff --git a/content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte
similarity index 100%
rename from content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/+page.svelte
rename to content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte
diff --git a/content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte
similarity index 100%
rename from content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/about/+page.svelte
rename to content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte
diff --git a/content/tutorial/02-sveltekit/02-routing/02-endpoints/app-b/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte
similarity index 100%
rename from content/tutorial/02-sveltekit/02-routing/02-endpoints/app-b/src/routes/about/+page.svelte
rename to content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte
From d4080dde6a661090b6d7d58bfd90bc2f52ed0780 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 17 Oct 2022 20:45:35 +0200
Subject: [PATCH 002/177] more chapters
---
.../app-a/src/routes/api/+server.js | 2 ++
.../04-loading-layout-data/README.md | 28 ++++++++++++++++
.../app-a/src/routes/+layout.js | 0
.../app-a/src/routes/+layout.svelte | 6 ++++
.../app-a/src/routes/+page.js | 4 +++
.../app-a/src/routes/+page.svelte | 5 +++
.../app-a/src/routes/about/+page.svelte | 1 +
.../app-a/src/routes/api/+server.js | 5 +++
.../app-b/src/routes/+layout.js | 4 +++
.../app-b/src/routes/+layout.svelte | 10 ++++++
.../05-loading-server-data/README.md | 28 ++++++++++++++++
.../app-a/src/routes/+page.server.js | 1 +
.../app-a/src/routes/+page.svelte | 1 +
.../app-a/src/routes/fake-db.js | 3 ++
.../app-b/src/routes/+page.server.js | 6 ++++
.../app-b/src/routes/+page.svelte | 5 +++
.../app-b/src/routes/fake-db.js | 3 ++
.../06-loading-layout-server-data/README.md | 33 +++++++++++++++++++
.../app-a/src/routes/+layout.server.js | 1 +
.../app-a/src/routes/+layout.svelte | 6 ++++
.../app-a/src/routes/+page.server.js | 6 ++++
.../app-a/src/routes/+page.svelte | 5 +++
.../app-a/src/routes/about/+page.svelte | 1 +
.../app-a/src/routes/fake-db.js | 3 ++
.../app-b/src/routes/+layout.server.js | 6 ++++
.../app-b/src/routes/+layout.svelte | 10 ++++++
26 files changed, 183 insertions(+)
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/api/+server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/fake-db.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/fake-db.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/about/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/fake-db.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
index 7194f94f7..79b389602 100644
--- a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
+++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/api/+server.js
@@ -1,3 +1,5 @@
+// We'll get to +server.js in a later chapter
+
export function GET() {
return new Response('Hello from your API');
}
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/README.md b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/README.md
new file mode 100644
index 000000000..a023c6a3f
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/README.md
@@ -0,0 +1,28 @@
+---
+title: Loading Layout Data
+---
+
+Layouts can provide common UI across pages. They can also provide common data across pages.
+
+Providing this data is similar to the `load` function in `+page.js`, only that we place it inside `+layout.js` - notice the symmetry?
+
+Like in `+page.js`, this `load` function runs on the server when the user visits your page initially, and on the client for all further navigations - it's isomorphic. We call it a "shared `load` function". To harmonize the differences between client and server, use the `fetch` function passed to `load` to load data. The return type of the `load` function needs to be an object at the top level, below that everything is allowed. If we return a promise, it's awaited. The result is passed to the `data` prop inside `+layout.svelte`, so we can access it through `export let data`.
+
+Let's make the same call inside `src/routes/+layout.js` as we are already doing in `src/routes/+page.js`, switch the search param from `page` to `layout`:
+
+```svelte
++++
++++
+
---TODO---+++{data.greeting}+++
+```
+
+```js
++++export async function load({ fetch }) {
+ const greeting = await fetch('/api?layout').then((r) => r.text());
+ return { greeting };
+}+++
+```
+
+> The data for `+page.js` and `+layout.js` will be loaded in parallel, so your UI renders faster
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.js b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..4add7f227
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
@@ -0,0 +1,6 @@
+
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/about/+page.svelte
new file mode 100644
index 000000000..e71828071
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/about/+page.svelte
@@ -0,0 +1 @@
+About page
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/api/+server.js b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/api/+server.js
new file mode 100644
index 000000000..8ae732d1f
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/api/+server.js
@@ -0,0 +1,5 @@
+// We'll get to +server.js in a later chapter
+
+export function GET({ url }) {
+ return new Response('Hello ' + url.search);
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.js b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.js
new file mode 100644
index 000000000..8b1baa17a
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.js
@@ -0,0 +1,4 @@
+export async function load({ fetch }) {
+ const greeting = await fetch('/api?layout').then((r) => r.text());
+ return { greeting };
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
new file mode 100644
index 000000000..f1872144c
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
@@ -0,0 +1,10 @@
+
+
+
{data.greeting}
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/README.md b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/README.md
new file mode 100644
index 000000000..3306b47d4
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/README.md
@@ -0,0 +1,28 @@
+---
+title: Loading Data on the Server
+---
+
+We have seen how to load data for pages and layouts through `load` functions in `+page.js` and `+layout.js`. These functions run on both the server and the client. This has some advantages but also some drawbacks, for example you can't directly query your database, you have to use `fetch`.
+
+Luckily, SvelteKit provides a way to run a `load` _only_ on the server so you can access all your server-related data directly, by placing it inside `+page.server.js`. We call it a "server-only `load` function". The return type of the `load` function needs to be an object at the top level, and it needs to be serializable with `devalue`, which means JSON-objects and some JavaScript objects like `Date`s are allowed, but not custom classes for example. If we return a promise, it's awaited. The result is passed to the `data` prop inside `+page.svelte`, so we can access it through `export let data`.
+
+Let's make a call to our fake database inside `src/routes/+page.server.js` and show the result in `src/routes/+page.svelte`:
+
+```svelte
++++
++++
+
---TODO---+++{data.greeting}+++
+```
+
+```js
+import { db } from './fake-db.js';
+
++++export async function load() {
+ const greeting = await db.getGreeting();
+ return { greeting };
+}+++
+```
+
+> Noticed how we can place `fake-db.js` right next to our page and layout files without risking to accidentally creating another route? This is one of several advantages of our "`+X` creates a route-related file"-convention
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..fd61f4045
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.server.js
@@ -0,0 +1 @@
+import { db } from './fake-db';
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..c65158e7c
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+
TODO
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/fake-db.js b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/fake-db.js
new file mode 100644
index 000000000..19e094e31
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/fake-db.js
@@ -0,0 +1,3 @@
+export const db = {
+ getGreeting: () => Promise.resolve('Hello from your fake data base')
+};
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.server.js
new file mode 100644
index 000000000..8e2b361b4
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.server.js
@@ -0,0 +1,6 @@
+import { db } from './fake-db';
+
+export async function load() {
+ const greeting = await db.getGreeting();
+ return { greeting };
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..7416c4d70
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
{data.greeting}
diff --git a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/fake-db.js b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/fake-db.js
new file mode 100644
index 000000000..19e094e31
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/fake-db.js
@@ -0,0 +1,3 @@
+export const db = {
+ getGreeting: () => Promise.resolve('Hello from your fake data base')
+};
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/README.md b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/README.md
new file mode 100644
index 000000000..076e5acef
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/README.md
@@ -0,0 +1,33 @@
+---
+title: Loading Layout Data on the Server
+---
+
+Layouts can provide common UI across pages. They can also provide common data across pages. Like pages, they can do so from a shared `load` function or a server-only `load` function.
+
+If you have worked through the previous tutorial chapters in order, you may notice a pattern by now:
+
+- Load data for a page inside `+page.js` or `+page.server.js`
+- Load data for a layout inside `+layout.js` or `+layout.server.js`
+
+In this chapter, we look at the last of those four possibilities by placing the `load` function inside `+layout.server.js`. We call it a "server-only `load` function". The return type of the `load` function needs to be an object at the top level, and it needs to be serializable with `devalue`, which means JSON-objects and some JavaScript objects like `Date`s are allowed, but not custom classes for example. If we return a promise, it's awaited. The result is passed to the `data` prop inside `+layout.svelte`, so we can access it through `export let data`.
+
+Let's make a call to our fake database inside `src/routes/+layout.server.js` and show the result in `src/routes/+layout.svelte`:
+
+```svelte
++++
++++
+
---TODO---+++{data.greeting}+++
+```
+
+```js
+import { db } from './fake-db.js';
+
++++export async function load() {
+ const greeting = await db.getGreeting('layout');
+ return { greeting };
+}+++
+```
+
+> The data for `+page.server.js` and `+layout.server.js` will be loaded in parallel, so your UI renders faster
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.server.js b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.server.js
new file mode 100644
index 000000000..fd61f4045
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.server.js
@@ -0,0 +1 @@
+import { db } from './fake-db';
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
new file mode 100644
index 000000000..4add7f227
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
@@ -0,0 +1,6 @@
+
TODO
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..9d6bb6027
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.server.js
@@ -0,0 +1,6 @@
+import { db } from './fake-db';
+
+export async function load() {
+ const greeting = await db.getGreeting('page');
+ return { greeting };
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..7416c4d70
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.svelte
@@ -0,0 +1,5 @@
+
+
+
{data.greeting}
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/about/+page.svelte
new file mode 100644
index 000000000..e71828071
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/about/+page.svelte
@@ -0,0 +1 @@
+About page
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/fake-db.js b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/fake-db.js
new file mode 100644
index 000000000..fa47d6688
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/fake-db.js
@@ -0,0 +1,3 @@
+export const db = {
+ getGreeting: (toGreet) => Promise.resolve('Hello ' + toGreet)
+};
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.server.js b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.server.js
new file mode 100644
index 000000000..dc4a1fefa
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.server.js
@@ -0,0 +1,6 @@
+import { db } from './fake-db';
+
+export async function load() {
+ const greeting = await db.getGreeting('layout');
+ return { greeting };
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
new file mode 100644
index 000000000..f1872144c
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
@@ -0,0 +1,10 @@
+
+
+
{data.greeting}
+
+
From 85a364337518faab2c6622df1a2b1da47e5f0b62 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 17 Oct 2022 20:53:04 +0200
Subject: [PATCH 003/177] slots
---
.../04-loading-layout-data/app-a/src/routes/+layout.svelte | 2 ++
.../04-loading-layout-data/app-b/src/routes/+layout.svelte | 2 ++
.../app-a/src/routes/+layout.svelte | 2 ++
.../app-b/src/routes/+layout.svelte | 2 ++
4 files changed, 8 insertions(+)
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
index 4add7f227..a72f829fc 100644
--- a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.svelte
@@ -4,3 +4,5 @@
HomeAbout
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
index f1872144c..199ccc0e5 100644
--- a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
+++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-b/src/routes/+layout.svelte
@@ -8,3 +8,5 @@
HomeAbout
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
index 4add7f227..a72f829fc 100644
--- a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.svelte
@@ -4,3 +4,5 @@
HomeAbout
+
+
diff --git a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
index f1872144c..199ccc0e5 100644
--- a/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
+++ b/content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-b/src/routes/+layout.svelte
@@ -8,3 +8,5 @@
HomeAbout
+
+
From 4581ff3f5f1b5130498e42c7e61498d02ddc8e44 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 18 Oct 2022 15:29:31 +0200
Subject: [PATCH 004/177] chapter skeletons
---
.../02-sveltekit/02-routing/07-params/README.md | 13 +++++++++++++
.../07-params/app-a/src/routes/+page.svelte | 1 +
.../07-params/app-b/src/routes/+page.svelte | 1 +
.../02-sveltekit/02-routing/08-endpoints/README.md | 9 +++++++++
.../08-endpoints/app-a/src/routes/+page.svelte | 1 +
.../08-endpoints/app-a/src/routes/api/+server.js | 0
.../08-endpoints/app-b/src/routes/api/+server.js | 3 +++
.../02-sveltekit/02-routing/10-endpoints/README.md | 5 -----
.../10-endpoints/app-a/src/routes/+page.svelte | 4 ----
.../app-a/src/routes/about/+page.svelte | 4 ----
.../app-b/src/routes/about/+page.svelte | 4 ----
11 files changed, 28 insertions(+), 17 deletions(-)
create mode 100644 content/tutorial/02-sveltekit/02-routing/07-params/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md
create mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/api/+server.js
create mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js
delete mode 100644 content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md
delete mode 100644 content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte
delete mode 100644 content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte
delete mode 100644 content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte
diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/README.md b/content/tutorial/02-sveltekit/02-routing/07-params/README.md
new file mode 100644
index 000000000..97cb71742
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/07-params/README.md
@@ -0,0 +1,13 @@
+---
+title: Route Parameters
+---
+
+Many URLs are static, but sometimes it's useful to make them dynamic at certain parts of the URL. This is where route parameters come in.
+
+A route parameter is created by adding square brackets around a valid variable name. For a route like `src/routes/[foo]/bar/+page.svelte`, resulting valid URLs are `a/bar`, `b/bar`, `c/bar`, ... and so on.
+
+Defining a route parameter is only half-useful if our page always shows the same for each possible parameter value. Let's access the parameter value in our `load` function through the `params` object to load data corresponding to the parameter.
+
+TODO example use case
+
+> Multiple route parameters can appear _within_ one URL segment, as long as they are separated by at least one static character: `foo/[bar]x[baz]` is a valid route where `[bar]` and `[bar]` are dynamic parameters.
diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..1333ed77b
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+TODO
diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..1333ed77b
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/+page.svelte
@@ -0,0 +1 @@
+TODO
diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md b/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md
new file mode 100644
index 000000000..b5f29710c
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md
@@ -0,0 +1,9 @@
+---
+title: Endpoints
+---
+
+So far, we have loaded data directly related to a page. Besides that, SvelteKit also provides you a way to retrieve and manipulate data through endpoints.
+
+An endpoint is created by putting a `+server.js` in a directory. `src/routes/api/user/+server.js` becomes an endpoint accessible at `api/user`. The endpoint can provide methods corresponding to the http verbs you already may know from previous experience: `GET`, `PUT`, `POST`, `PATCH` and `DELETE`.
+
+TODO example use case
diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..1333ed77b
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+TODO
diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/api/+server.js b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/api/+server.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js
new file mode 100644
index 000000000..2b90cc4ba
--- /dev/null
+++ b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js
@@ -0,0 +1,3 @@
+export function GET() {
+ return new Response();
+}
diff --git a/content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md b/content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md
deleted file mode 100644
index 62a7c7d07..000000000
--- a/content/tutorial/02-sveltekit/02-routing/10-endpoints/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Endpoints
----
-
-TODO
diff --git a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte
deleted file mode 100644
index fbb0f5613..000000000
--- a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/+page.svelte
+++ /dev/null
@@ -1,4 +0,0 @@
-
From f392697de7e214c4f5addb674e7f10b2d7043b05 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Fri, 21 Oct 2022 14:17:35 +0200
Subject: [PATCH 005/177] mutating data section
---
.../03-mutating-data/01-forms/README.md | 32 ++++++++++++
.../01-forms/app-a/src/routes/+page.server.js | 0
.../01-forms/app-a/src/routes/+page.svelte | 1 +
.../app-a/src/routes/user/+page.svelte | 1 +
.../01-forms/app-b/src/routes/+page.server.js | 7 +++
.../01-forms/app-b/src/routes/+page.svelte | 7 +++
.../02-form-validation/README.md | 42 +++++++++++++++
.../app-a/src/routes/+page.server.js | 7 +++
.../app-a/src/routes/+page.svelte | 7 +++
.../app-a/src/routes/user/+page.svelte | 1 +
.../app-b/src/routes/+page.server.js | 11 ++++
.../app-b/src/routes/+page.svelte | 14 +++++
.../03-named-form-actions/README.md | 52 +++++++++++++++++++
.../app-a/src/routes/+page.server.js | 11 ++++
.../app-a/src/routes/+page.svelte | 12 +++++
.../app-a/src/routes/user/+page.svelte | 1 +
.../app-b/src/routes/+page.server.js | 18 +++++++
.../app-b/src/routes/+page.svelte | 16 ++++++
.../04-progressive-enhancement/README.md | 31 +++++++++++
.../app-a/src/routes/+page.server.js | 18 +++++++
.../app-a/src/routes/+page.svelte | 16 ++++++
.../app-a/src/routes/user/+page.svelte | 1 +
.../app-b/src/routes/+page.svelte | 17 ++++++
.../05-customizing-use-enhance/README.md | 33 ++++++++++++
.../app-a/src/routes/+page.server.js | 18 +++++++
.../app-a/src/routes/+page.svelte | 17 ++++++
.../app-a/src/routes/user/+page.svelte | 1 +
.../app-b/src/routes/+page.svelte | 32 ++++++++++++
.../06-mutation-through-endpoints/README.md | 7 +++
.../app-a/src/routes/+page.svelte | 1 +
.../app-b/src/routes/+page.svelte | 1 +
31 files changed, 433 insertions(+)
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/user/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/user/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/user/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/user/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.server.js
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/user/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/README.md
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-b/src/routes/+page.svelte
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md
new file mode 100644
index 000000000..3c3b22758
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md
@@ -0,0 +1,32 @@
+---
+title: Forms
+---
+
+A fundamental part of a web app is not only loading data, but also manipulating and saving it back. The way to do this on the web is to use `+++
+```
+
+A couple of things to note
+
+- this is plain old HTML, there's nothing SvelteKit-specific about this
+- we use `method="POST"` which means when the form is submitted, it does a `POST` request to the page it's on, sending the form value in the body, which is much safer compared to `method="GET"` because the values would appear in the search query.
+
+That's all we need for the HTML part. Let's handle that form action inside `+page.server.js`. For that, we export an `actions` object with the property `default` in it. This property is a function from which we will redirect to the user page - for now, without checking the credentials (we'll do that in the next section). We do this by importing `redirect` from `@sveltejs/kit` and `throw`ing it with a redirect status code and a destination.
+
+```js
++++import { redirect } from '@sveltejs/kit';
+
+export const actions = {
+ default: () => {
+ throw redirect(307, '/user');
+ }
+}+++
+```
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..92e35087e
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/+page.svelte
@@ -0,0 +1 @@
+
Please log in
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/user/+page.svelte
new file mode 100644
index 000000000..15c324713
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-a/src/routes/user/+page.svelte
@@ -0,0 +1 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/README.md b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/README.md
new file mode 100644
index 000000000..c1205316b
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/README.md
@@ -0,0 +1,42 @@
+---
+title: Form Validation
+---
+
+In the previous section we created a form and redirected the user without even checking the credentials - a rather insecure application we built there. Let's change that by adding some validation!
+
+In `+page.server.js` we do that by first getting the form data from the `request` object that is passed to the action function. We then check if the credentials are valid - let's hardcode them for the sake of this tutorial. If the credentials are invalid, we return `invalid` imported from `@sveltejs/kit` with a status code and an error object:
+
+```js
+import { redirect, +++invalid+++ } from '@sveltejs/kit';
+
+export const actions = {
+ default: +++async+++ (+++request+++) => {
+ +++const fields = await request.formData();
+ if (fields.get('email') !== 'svelte@kit.dev' || fields.get('password') !== 'tutorial') {
+ return invalid(422, { message: 'Invalid Credentials' });
+ }+++
+ throw redirect(307, '/user');
+ }
+}
+```
+
+What's left to do is displaying that error message. Whatever is returned from `invalid` will be part of the `forms` property in `+page.svelte`, which we can access through `export let forms`.
+
+```svelte
+++++++
+
+
Please log in
+
+
+```
+
+> `form` is set to `null` initially and will be filled with whatever you return from `invalid`. You can also return data in case of a successful submission.
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..f0feea49f
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.server.js
@@ -0,0 +1,7 @@
+import { redirect } from '@sveltejs/kit';
+
+export const actions = {
+ default: () => {
+ throw redirect(307, '/user');
+ }
+};
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..62424d768
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/+page.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/README.md b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/README.md
new file mode 100644
index 000000000..1ae40d73f
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/README.md
@@ -0,0 +1,52 @@
+---
+title: Named Form Actions
+---
+
+Some pages have more than one `
+```
+
+The `?` means that this string is appended as a query string to the existing URL, the `/` is used to uniquly identify the query parameter as a form action, and the name can then be whatever we want.
+
+> The `action`/`formAction` attributes are standard HTML attributes, and you can also link to actions on other pages through them.
+
+In `+page.server.js`, we react to these named actions by adding them as properties to the `actions` object:
+
+```js
+import { redirect, invalid } from '@sveltejs/kit';
+
+export const actions = {
+ ---default---+++login+++: async (request) => {
+ const fields = await request.formData();
+ if (fields.get('email') !== 'svelte@kit.dev' || fields.get('password') !== 'tutorial') {
+ return invalid(422, { message: 'Invalid Credentials' });
+ }
+ throw redirect(307, '/user');
+ },
+ +++register: async (request) => {
+ const fields = await request.formData();
+ if (fields.get('email') === 'svelte@kit.dev') {
+ return invalid(422, { message: 'Email already in use' });
+ }
+ throw redirect(307, '/user');
+ }+++
+}
+```
+
+> We can't have default actions next to named actions, because if you POST to a named action without a redirect, the query parameter is persisted in the URL, which means the next default POST would go through the named action from before.
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..dbbfa49a4
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.server.js
@@ -0,0 +1,11 @@
+import { redirect } from '@sveltejs/kit';
+
+export const actions = {
+ default: async (request) => {
+ const fields = await request.formData();
+ if (fields.get('email') !== 'svelte@kit.dev' || fields.get('password') !== 'tutorial') {
+ return invalid(422, { message: 'Invalid Credentials' });
+ }
+ throw redirect(307, '/user');
+ }
+};
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..e7e1316bc
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/+page.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/user/+page.svelte
new file mode 100644
index 000000000..15c324713
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-a/src/routes/user/+page.svelte
@@ -0,0 +1 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md
new file mode 100644
index 000000000..8b9dfe648
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md
@@ -0,0 +1,31 @@
+---
+title: Progressive Enhancement
+---
+
+So far, the `
+```
+
+And that's all! Now, when JavaScript is enabled, `use:enhance` will emulate the browser-native behaviour, just without the full-page reloads. It will:
+
+- update the `form` property - but only if the action is on the same page you're submitting from. So for example if your form looks like
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/user/+page.svelte
new file mode 100644
index 000000000..15c324713
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/user/+page.svelte
@@ -0,0 +1 @@
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/README.md b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/README.md
new file mode 100644
index 000000000..4ff45b952
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/README.md
@@ -0,0 +1,33 @@
+---
+title: Customizing `use:enhance`
+---
+
+In the last chapter we have seen how to progressively enhance our `
+```
+
+`submitting = true` is set as soon as the user presses on of the buttons. The returned callback function is called as soon as the form submission was processed by the server and a response was returned. We call the `update` function to get the native browser behavior without the reloads (updating the `form` prop and so on) and set `submitting` to `false` afterwards.
+
+> `use:enhance` provides a range of properties which makes it very customizable. You can also abort submissions by calling a `cancel` function for example. Play around with it a little to see what's possible!
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.server.js
new file mode 100644
index 000000000..369fcce46
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.server.js
@@ -0,0 +1,18 @@
+import { redirect, invalid } from '@sveltejs/kit';
+
+export const actions = {
+ login: async (request) => {
+ const fields = await request.formData();
+ if (fields.get('email') !== 'svelte@kit.dev' || fields.get('password') !== 'tutorial') {
+ return invalid(422, { message: 'Invalid Credentials' });
+ }
+ throw redirect(307, '/user');
+ },
+ register: async (request) => {
+ const fields = await request.formData();
+ if (fields.get('email') === 'svelte@kit.dev') {
+ return invalid(422, { message: 'Email already in use' });
+ }
+ throw redirect(307, '/user');
+ }
+};
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..0d38015c1
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/+page.svelte
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/README.md b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/README.md
new file mode 100644
index 000000000..815128117
--- /dev/null
+++ b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/README.md
@@ -0,0 +1,7 @@
+---
+title: Using Endpoints for Data Mutation
+---
+
+Sometimes it's fine to assume the user has JavaScript enabled, for example when creating an internal business app. Some forms of interaction also get rather hard to implement using `
+
+
diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js
deleted file mode 100644
index e69de29bb..000000000
diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js
index e335d6c3d..3e0161f87 100644
--- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js
+++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js
@@ -1,5 +1,5 @@
import { error } from '@sveltejs/kit';
-export function load() {
- throw error(404, 'Page not found');
+export function load({ url }) {
+ throw error(404, `Page ${url.pathname} not found`);
}
diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md
index bcc468e49..a5f67e77b 100644
--- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md
@@ -4,11 +4,11 @@ title: Param Matchers
A route like `src/routes/archive/[page]` would match `/archive/3`, but it would also match `/archive/potato`. We don't want that. You can ensure that route parameters are well-formed by adding a matcher — which takes the parameter string (`"3"` or `"potato"`) and returns `true` if it is valid.
-First add a matcher to your `params` directory:
+First add a `params` directory (all matchers go in there) with a matcher in it:
```diff
src/
-├ params/
++├ params/
+│ └ integer.js
├ routes/
│ ├ archive/
@@ -40,6 +40,6 @@ src/
│ └ +page.svelte
```
-If the pathname doesn't match, SvelteKit will try to match other routes (using the sort order specified below), before eventually returning a 404.
+Now, whenever someone navigates to that page, the validator will try to match the `[page]` parameter to see if it's valid. If the pathname doesn't match, SvelteKit will try to match other routes (using the sort order specified below), before eventually returning a 404.
> Matchers run both on the server and in the browser.
From 0cf6e874ec26d02345584cfacf380e5424da86a5 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Fri, 2 Dec 2022 14:51:57 +0100
Subject: [PATCH 031/177] fix
---
.../01-advanced-routing/04-layout-groups/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md
index c69965f7d..82d7e0482 100644
--- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md
+++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md
@@ -8,16 +8,16 @@ In this example we have three pages — the home page, the about page, and a pri
A group is denoted by its surrounding parantheses. A group is ignored when creating the url: `(marketing)/price/+page.svelte` means that the URL to access this page is `/price`.
-Create a `(marketing)` folder inside `routes` and move the home and pricing page inside. Last, create a new `+layout.svelte` inside `(marketing)`:
+Create a `(marketing)` folder inside `routes` and move the home and pricing page inside (implementation hint: it's easiest if you use the rename feature). Last, create a new `+layout.svelte` inside `(marketing)`:
```diff
src/routes/
+├ (marketing)
-│ ├ about/
+│ ├ pricing/
│ │ └ +page.svelte
+│ ├ +layout.svelte
+│ └ +page.svelte
-├ pricing/
+├ about/
│ └ +page.svelte
├ +layout.svelte
-└ +page.svelte
From e1c17dd8f76e3f9227da6c44005688a8a2d0c96f Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Fri, 2 Dec 2022 17:17:04 +0100
Subject: [PATCH 032/177] environment variables tutorial
---
.gitignore | 1 +
.../01-private-static/README.md | 24 ++++++++++++++++
.../01-private-static/app-a/.env | 1 +
.../app-a/src/routes/+page.svelte | 7 +++++
.../app-b/src/routes/+page.svelte | 7 +++++
.../02-public-static/README.md | 28 +++++++++++++++++++
.../02-public-static/app-a/.env | 1 +
.../app-a/src/routes/+page.svelte | 8 ++++++
.../02-public-static/app-b/.env | 1 +
.../app-b/src/routes/+page.svelte | 8 ++++++
.../03-private-dynamic/README.md | 21 ++++++++++++++
.../03-private-dynamic/app-a/.env | 1 +
.../app-a/src/routes/+page.svelte | 7 +++++
.../app-b/src/routes/+page.svelte | 7 +++++
.../04-public-dynamic/README.md | 28 +++++++++++++++++++
.../04-public-dynamic/app-a/.env | 1 +
.../app-a/src/routes/+page.svelte | 8 ++++++
.../04-public-dynamic/app-b/.env | 1 +
.../app-b/src/routes/+page.svelte | 8 ++++++
.../02-environment-variables/meta.json | 3 ++
src/lib/server/content.js | 5 ++--
21 files changed, 174 insertions(+), 2 deletions(-)
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/README.md
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/README.md
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/README.md
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/.env
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/src/routes/+page.svelte
create mode 100644 content/tutorial/04-advanced-sveltekit/02-environment-variables/meta.json
diff --git a/.gitignore b/.gitignore
index d79e7a25e..3264f4d0c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
.env
.env.*
!.env.example
+!/content/tutorial/04-advanced-sveltekit/02-environment-variables/**/.env
.apps
.vercel
/content/tutorial/common/.svelte-kit
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
new file mode 100644
index 000000000..44f43e822
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
@@ -0,0 +1,24 @@
+---
+title: Private static environment variables
+---
+
+Like a good friend, SvelteKit keeps your secrets. When writing your backend and frontend in the same repository, it can be easy to accidentally import sensitive data into your front-end code (environment variables containing API keys, for example). SvelteKit helps you avoiding that through private environment variables.
+
+Environment variables are [loaded by Vite](https://vitejs.dev/guide/env-and-mode.html#env-files) from `.env` files and `process.env` (a NodeJS global). You can then access them through `import.meta.env.X` where `X` is the name of your environment variable. Vite already helps us by only exposing environment variables that start with `VITE_` (that prefix is configurable), others are considered private, but it has two drawbacks:
+
+1. There's no way to distinguish between variables we want to expose on the server and on the client. It's easy to accidentally expose sensitive data to your front-end code
+2. It's not type safe
+
+SvelteKit solves both these drawbacks through it's `$env/*` exports. Let's replace the environment variable in `src/routes/+page.svelte` using an import with the same name from `$env/static/private`:
+
+```svelte
+
+
+
My secret environment variable is: {---import.meta.env.VITE_SECRET---+++VITE_SECRET+++}
+```
+
+As you can see, we now get an error, since the variable is marked as private - crisis averted!
+
+> Don't commit your `.env` file to Git if it contains sensitive information such as API keys!
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/.env
new file mode 100644
index 000000000..b7a48698b
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/.env
@@ -0,0 +1 @@
+VITE_SECRET="Oh no, you shouldn't see this!"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..d1f8a54d6
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-a/src/routes/+page.svelte
@@ -0,0 +1,7 @@
+
+
+
+ My secret environment variable is:
+ {import.meta.env.VITE_SECRET}
+
+ My secret environment variable is: {VITE_SECRET}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/README.md b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/README.md
new file mode 100644
index 000000000..b293e3f46
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/README.md
@@ -0,0 +1,28 @@
+---
+title: Public static environment variables
+---
+
+In the previous section we saw how to leverage `$env/static/private` for secret environment variables which can't be exposed to front-end code. But what to do if we _do_ want to expose such an environment variable, because it's public?
+
+For this, first prefix the environment variable inside `.env` with `PUBLIC_`. This prefix marks an environment variable as eligible for use in front-end code.
+
+```js
++++PUBLIC_+++KEY="It's ok to see this"
+```
+
+Then switch the import in `src/routes/+page.svelte` from `$env/static/private` to `$env/static/public` and prefix the variable with `PUBLIC_` aswell:
+
+```svelte
+
+
+
+ My public environment variable is:
+ {+++PUBLIC_+++KEY}
+
+```
+
+The `PUBLIC_` prefix on the imported variable might seem redundant at first - but that's actually a good thing! You immediately see that this is a public environment variable without looking up where it's imported from, and search-and-replace across the code base get's easier.
+
+> Don't commit your `.env` file to Git if it contains sensitive information such as API keys!
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/.env
new file mode 100644
index 000000000..1dec42352
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/.env
@@ -0,0 +1 @@
+KEY="It's ok to see this"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..43b056a94
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-a/src/routes/+page.svelte
@@ -0,0 +1,8 @@
+
+
+
+ My public environment variable is:
+ {PUBLIC_KEY}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/.env
new file mode 100644
index 000000000..c33a0b6ae
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/.env
@@ -0,0 +1 @@
+PUBLIC_KEY="It's ok to see this"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..3e58c4f05
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/02-public-static/app-b/src/routes/+page.svelte
@@ -0,0 +1,8 @@
+
+
+
+ My public environment variable is:
+ {KEY}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/README.md b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/README.md
new file mode 100644
index 000000000..ad76923eb
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/README.md
@@ -0,0 +1,21 @@
+---
+title: Private dynamic environment variables
+---
+
+Some environment variables aren't statically known at build time - for example they could be injected through the deployment platform at runtime. SvelteKit has you covered for these situations with a similar tuple of exports.
+
+To access dynamic environment variables, replace the `$env/static/private` import with `$env/dynamic/private` and use the `env` variable instead, since we can't know the name statically:
+
+```svelte
+
+
+
My secret environment variable is: {+++env.+++SECRET}
+```
+
+As you can see, we still get an error, since the variable is marked as private. You will also get auto-completion on the `env` object if you added this variable to your local `.env` file.
+
+> In dev, `$env/dynamic` always includes environment variables from `.env`. In prod, this behavior will depend on your adapter.
+
+> Don't commit your `.env` file to Git if it contains sensitive information such as API keys!
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/.env
new file mode 100644
index 000000000..874cd21f7
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/.env
@@ -0,0 +1 @@
+SECRET="Oh no, you shouldn't see this!"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..0c894524a
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-a/src/routes/+page.svelte
@@ -0,0 +1,7 @@
+
+
+
+ My secret environment variable is: {env.SECRET}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/README.md b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/README.md
new file mode 100644
index 000000000..e50795abd
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/README.md
@@ -0,0 +1,28 @@
+---
+title: Public dynamic environment variables
+---
+
+In the previous section we saw how to leverage `$env/dynamic/private` for secret environment variables which can't be exposed to front-end code. Similar to their static counterpart, there's also an export to import public environment variables.
+
+For this, first prefix the environment variable inside `.env` with `PUBLIC_`. This prefix marks an environment variable as eligible for use in front-end code.
+
+```js
++++PUBLIC_+++KEY="It's ok to see this"
+```
+
+Then switch the import in `src/routes/+page.svelte` from `$env/static/private` to `$env/static/public` and prefix the variable with `PUBLIC_` aswell:
+
+```svelte
+
+
+
+ My public environment variable is:
+ {env.+++PUBLIC_+++KEY}
+
+```
+
+The `PUBLIC_` prefix on the imported variable might seem redundant at first - but that's actually a good thing! You immediately see that this is a public environment variable without looking up where it's imported from, and search-and-replace across the code base get's easier.
+
+> Don't commit your `.env` file to Git if it contains sensitive information such as API keys!
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/.env
new file mode 100644
index 000000000..1dec42352
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/.env
@@ -0,0 +1 @@
+KEY="It's ok to see this"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/src/routes/+page.svelte
new file mode 100644
index 000000000..c2a21eee7
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-a/src/routes/+page.svelte
@@ -0,0 +1,8 @@
+
+
+
+ My public environment variable is:
+ {env.KEY}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/.env b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/.env
new file mode 100644
index 000000000..c33a0b6ae
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/.env
@@ -0,0 +1 @@
+PUBLIC_KEY="It's ok to see this"
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/src/routes/+page.svelte
new file mode 100644
index 000000000..ca77b0561
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/04-public-dynamic/app-b/src/routes/+page.svelte
@@ -0,0 +1,8 @@
+
+
+
+ My public environment variable is:
+ {env.PUBLIC_KEY}
+
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/meta.json b/content/tutorial/04-advanced-sveltekit/02-environment-variables/meta.json
new file mode 100644
index 000000000..877f1f0d0
--- /dev/null
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/meta.json
@@ -0,0 +1,3 @@
+{
+ "title": "Environment Variables"
+}
diff --git a/src/lib/server/content.js b/src/lib/server/content.js
index 233b2ba88..bff0f1222 100644
--- a/src/lib/server/content.js
+++ b/src/lib/server/content.js
@@ -11,7 +11,8 @@ const text_files = new Set([
'.css',
'.svg',
'.html',
- '.md'
+ '.md',
+ '.env'
]);
const excluded = new Set(['.DS_Store', '.gitkeep', '.svelte-kit', 'package-lock.json']);
@@ -211,7 +212,7 @@ export function walk(cwd, options = {}) {
walk_dir(name + '/', depth + 1);
} else {
- const text = text_files.has(path.extname(name));
+ const text = text_files.has(path.extname(name) || path.basename(name));
const contents = fs.readFileSync(resolved, text ? 'utf-8' : 'base64');
result[name] = {
From e27059dd5206044757b1f60583bac9e98bcf6ae6 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Fri, 2 Dec 2022 17:38:41 +0100
Subject: [PATCH 033/177] fixes
---
.../01-private-static/README.md | 12 +++++++-----
.../02-public-static/app-a/src/routes/+page.svelte | 4 ++--
.../02-public-static/app-b/src/routes/+page.svelte | 4 ++--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
index 44f43e822..ce91815c8 100644
--- a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
+++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/README.md
@@ -4,12 +4,12 @@ title: Private static environment variables
Like a good friend, SvelteKit keeps your secrets. When writing your backend and frontend in the same repository, it can be easy to accidentally import sensitive data into your front-end code (environment variables containing API keys, for example). SvelteKit helps you avoiding that through private environment variables.
-Environment variables are [loaded by Vite](https://vitejs.dev/guide/env-and-mode.html#env-files) from `.env` files and `process.env` (a NodeJS global). You can then access them through `import.meta.env.X` where `X` is the name of your environment variable. Vite already helps us by only exposing environment variables that start with `VITE_` (that prefix is configurable), others are considered private, but it has two drawbacks:
+Environment variables are [loaded by Vite](https://vitejs.dev/guide/env-and-mode.html#env-files) from `.env` files and `process.env` (a NodeJS global). You can then access them through `import.meta.env.X` where `X` is the name of your environment variable. Vite already helps us by only exposing environment variables that start with `VITE_` (that prefix is configurable), others are considered private. It has two drawbacks though:
-1. There's no way to distinguish between variables we want to expose on the server and on the client. It's easy to accidentally expose sensitive data to your front-end code
-2. It's not type safe
+- There's no way to distinguish between variables we want to expose on the server and on the client. It's easy to accidentally expose sensitive data to your front-end code
+- It's not type safe
-SvelteKit solves both these drawbacks through it's `$env/*` exports. Let's replace the environment variable in `src/routes/+page.svelte` using an import with the same name from `$env/static/private`:
+SvelteKit solves both these drawbacks through its `$env/*` exports. Let's replace the environment variable in `src/routes/+page.svelte` using an import with the same name from `$env/static/private`:
```svelte
My public environment variable is:
- {PUBLIC_KEY}
+ {KEY}
My public environment variable is:
- {KEY}
+ {PUBLIC_KEY}
From d1dfdf3b6721f1c54110cefbab9c0e5ec09b941a Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:01:06 +0100
Subject: [PATCH 034/177] Update
content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
Co-authored-by: Rich Harris
---
.../02-sveltekit/01-concepts/03-server-and-client/README.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md b/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
index 94eb10946..ccdeb3cb3 100644
--- a/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
@@ -8,8 +8,6 @@ A SvelteKit app can be thought of as two distinct entities working in tandem —
'Client' refers to the JavaScript that loads in the browser.
-SvelteKit makes the two communicate with each other seamlessly. It takes care of all the annoying stuff so you don't have to.
-
-On first page hit, SvelteKit will render the HTML on the server and send it to the browser. This means content is visible as fast as possible to the user. SvelteKit will then take over that HTML in a process called hydration, so that subsequent navigations will happen in the browser, allowing for a better user experience.
+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 to your liking if you want - SvelteKit is very versatile!
From 7f9bfd99d0835e337f05f2ca9b42b68c80a29318 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:01:27 +0100
Subject: [PATCH 035/177] Update
content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
Co-authored-by: Rich Harris
---
.../02-sveltekit/01-concepts/03-server-and-client/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md b/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
index ccdeb3cb3..e9b409b79 100644
--- a/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md
@@ -10,4 +10,4 @@ A SvelteKit app can be thought of as two distinct entities working in tandem —
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 to your liking if you want - SvelteKit is very versatile!
+> You can [adjust this behavior](https://kit.svelte.dev/docs/page-options) as needed. SvelteKit is very versatile!
From 78e3c8907a8530cbf707f3f89cc92885c4dd043c Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:01:44 +0100
Subject: [PATCH 036/177] Update
content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
Co-authored-by: Rich Harris
---
.../02-sveltekit/01-concepts/04-server-side-rendering/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md b/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
index 541d0bfbc..707c8ff54 100644
--- a/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
@@ -2,6 +2,6 @@
title: Server-side rendering
---
-Server-side rendering (SSR) is the generation of the page contents on the server. It's what SvelteKit does by default when a user first visits your site.
+Server-side rendering (SSR) is the generation of HTML on the server. It's what SvelteKit does by default for the initial page load when a user visits your site.
SSR is generally preferred for SEO (search engine optimization). While some search engines can index content that is dynamically generated on the client-side it may take longer even in these cases. It also tends to improve perceived performance and makes your app accessible to users if JavaScript fails or is disabled (which happens [more often than you probably think](https://kryogenix.org/code/browser/everyonehasjs.html)).
From 996935c7aefb3d8114fdaef3980b51c50fe95d2b Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:02:11 +0100
Subject: [PATCH 037/177] Update
content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
Co-authored-by: Rich Harris
---
.../02-sveltekit/01-concepts/04-server-side-rendering/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md b/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
index 707c8ff54..80d08787f 100644
--- a/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md
@@ -4,4 +4,4 @@ title: Server-side rendering
Server-side rendering (SSR) is the generation of HTML on the server. It's what SvelteKit does by default for the initial page load when a user visits your site.
-SSR is generally preferred for SEO (search engine optimization). While some search engines can index content that is dynamically generated on the client-side it may take longer even in these cases. It also tends to improve perceived performance and makes your app accessible to users if JavaScript fails or is disabled (which happens [more often than you probably think](https://kryogenix.org/code/browser/everyonehasjs.html)).
+SSR tends to improve performance and makes your app accessible to users if JavaScript fails or is disabled (which happens [more often than you probably think](https://kryogenix.org/code/browser/everyonehasjs.html)). It is also preferred for search engine optimization (SEO) — while some search engines can index content that is rendered in the browser with JavaScript, it happens less frequently and reliably.
From e77c99cfca9304022dd2da451f61bb6110ad3448 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:02:27 +0100
Subject: [PATCH 038/177] Update
content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
Co-authored-by: Rich Harris
---
.../tutorial/02-sveltekit/01-concepts/05-prerendering/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
index f2a49296a..2340d7d5a 100644
--- a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
@@ -2,7 +2,7 @@
title: Prerendering
---
-Prerendering means computing the contents of a page at build time and saving the HTML for display. You can opt in to prerendering on a per-page-basis or even the whole app when using SvelteKit.
+Prerendering means computing the contents of a page at build time and saving the HTML. You can opt in to prerendering for a single page, the entire app, or anything in between.
This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process is more expensive and prerendered content can only be updated by building and deploying a new version of the application.
From 660894db2d1d15fce5bc99dc4d3c4a3c80395202 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:02:49 +0100
Subject: [PATCH 039/177] Update
content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
Co-authored-by: Rich Harris
---
.../tutorial/02-sveltekit/01-concepts/05-prerendering/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
index 2340d7d5a..f68e040d7 100644
--- a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
@@ -4,7 +4,7 @@ title: Prerendering
Prerendering means computing the contents of a page at build time and saving the HTML. You can opt in to prerendering for a single page, the entire app, or anything in between.
-This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process is more expensive and prerendered content can only be updated by building and deploying a new version of the application.
+This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process takes longer, and prerendered content can only be updated by building and deploying a new version of the application.
Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain actions. Note that you can still prerender content that is loaded based on the page's parameters as long as all users will be seeing the same prerendered content.
From 683c83915cc037a6c86d125a9ba5a705f79310d1 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 18:03:26 +0100
Subject: [PATCH 040/177] Update
content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
Co-authored-by: Rich Harris
---
.../tutorial/02-sveltekit/01-concepts/05-prerendering/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
index f68e040d7..68be51dfc 100644
--- a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
+++ b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md
@@ -8,4 +8,4 @@ This approach has the same benefits as traditional server-rendered pages, but av
Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain actions. Note that you can still prerender content that is loaded based on the page's parameters as long as all users will be seeing the same prerendered content.
-Pre-rendered pages are not limited to static content. You can build personalized pages if user-specific data is fetched and rendered client-side. This is subject to the caveat that you will experience the downsides of not doing SSR for that content as discussed above.
+You can add user-specific data to a prerendered page by fetching it from the browser instead of using SvelteKit's built-in data loading, though this is generally not recommended since it will cause content to pop in as it loads.
From e4de675d72f3953d66c42db9998265bd6f4469e6 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 20:04:59 +0100
Subject: [PATCH 041/177] Update
content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
Co-authored-by: Rich Harris
---
content/tutorial/02-sveltekit/02-routing/02-layouts/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
index c3c3ff8e7..c074165c1 100644
--- a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
@@ -2,7 +2,7 @@
title: Layouts
---
-Sections of your app often share a common UI. To not repeat that code, we can use layouts.
+Different routes of your app will often share common UI. Instead of repeating it in each `+page.svelte` component, we can use a `+layout.svelte` component that applies to all routes in the same directory.
In this app we have two routes — `src/routes/+page.svelte`, and `src/routes/about/+page.svelte`. Both contain the same header which enables us to navigate around.
From bc5ab84e8629fc9fd86ea1e1a27ff964d8ddeaff Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 20:05:20 +0100
Subject: [PATCH 042/177] Update
content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
Co-authored-by: Rich Harris
---
.../tutorial/02-sveltekit/02-routing/02-layouts/README.md | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
index c074165c1..cb88949c7 100644
--- a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
@@ -4,11 +4,7 @@ title: Layouts
Different routes of your app will often share common UI. Instead of repeating it in each `+page.svelte` component, we can use a `+layout.svelte` component that applies to all routes in the same directory.
-In this app we have two routes — `src/routes/+page.svelte`, and `src/routes/about/+page.svelte`. Both contain the same header which enables us to navigate around.
-
-We can deduplicate this code by moving the common UI into a `+layout.svelte` file. All pages in the same folder or below this file will share that UI. The layout itself needs a `` at minimum to define where the content is projected.
-
-Let's move the duplicate content from `src/routes/+page.svelte` and `src/routes/about/+page.svelte` into `src/routes/+layout.svelte`. First, create that file:
+In this app we have two routes, `src/routes/+page.svelte` and `src/routes/about/+page.svelte`, that contain the same navigation UI. Let's create a new file, `src/routes/+layout.svelte`...
```diff
src/routes/
From 3cf476e4da5520b45875a43939a7983a948d1582 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Fri, 2 Dec 2022 20:05:40 +0100
Subject: [PATCH 043/177] Update
content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
Co-authored-by: Rich Harris
---
content/tutorial/02-sveltekit/02-routing/02-layouts/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
index cb88949c7..646bfce48 100644
--- a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
+++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md
@@ -14,7 +14,7 @@ src/routes/
└ +page.svelte
```
-Then remove the duplicated content from the `+page.svelte` files and add it to `+layout.svelte` instead:
+...and move the duplicated content from the `+page.svelte` files into the new `+layout.svelte` file. The `` element is where the page content will be rendered:
```svelte
+++