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 @@ + + +

Home

+ +

This is the home page.

+ + diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/about/+page.svelte new file mode 100644 index 000000000..17363fd17 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/about/+page.svelte @@ -0,0 +1,17 @@ + + +

About

+ +

This is the about page.

+ + diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+layout.svelte new file mode 100644 index 000000000..a4b160177 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+layout.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..ca3ffb790 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+page.svelte @@ -0,0 +1,3 @@ +

Home

+ +

This is the home page.

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 + + +

{+++data.+++greeting}

+``` + +```js ++++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-a/src/routes/+page.js b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.js new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..fd97ab1b5 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.svelte @@ -0,0 +1,12 @@ + + +

{greeting}

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 @@ +

TODO

+ + diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.js new file mode 100644 index 000000000..745604223 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.js @@ -0,0 +1,4 @@ +export async function load({ fetch }) { + const greeting = await fetch('/api?page').then((r) => r.text()); + return { greeting }; +} diff --git a/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..7416c4d70 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.svelte @@ -0,0 +1,5 @@ + + +

{data.greeting}

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 @@ Home About + + 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 @@ Home About + + 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 @@ Home About + + 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 @@ Home About + + 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 @@ -

Home

- -

This is the home page.

-

Go to the about page.

diff --git a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte deleted file mode 100644 index b74a0b67c..000000000 --- a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-a/src/routes/about/+page.svelte +++ /dev/null @@ -1,4 +0,0 @@ -

About

- -

This is the about page.

-

Go to the home page

diff --git a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte deleted file mode 100644 index 9a753d3d0..000000000 --- a/content/tutorial/02-sveltekit/02-routing/10-endpoints/app-b/src/routes/about/+page.svelte +++ /dev/null @@ -1,4 +0,0 @@ -

About

- -

This is the about page.

-

Go to the home page

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 `
` elements. + +Let's create a login form with email and password. First we write the HTML: + +```svelte ++++ + + + +
+++ +``` + +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 @@ +

Logged in!

diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.server.js new file mode 100644 index 000000000..f0feea49f --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/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/01-forms/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..62424d768 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte @@ -0,0 +1,7 @@ +

Please log in

+ +
+ + + +
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

+ +
+ + + +++{#if form?.message} + {form?.message} + {/if}+++ + +
+``` + +> `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 @@ +

Please log in

+ +
+ + + +
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/user/+page.svelte new file mode 100644 index 000000000..15c324713 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-a/src/routes/user/+page.svelte @@ -0,0 +1 @@ +

Logged in!

diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js new file mode 100644 index 000000000..dbbfa49a4 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/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/02-form-validation/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..1663d3525 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte @@ -0,0 +1,14 @@ + + +

Please log in

+ +
+ + + {#if form?.message} + {form?.message} + {/if} + +
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 `
`. That's why SvelteKit supports named form actions. + +Let's add a "Register" button to our existing form and introduce two form actions named `login` and `register`: + +```svelte + + + + + + {#if form?.message} + {form?.message} + {/if} + + ++++++ +
+``` + +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 @@ + + +
+ + + {#if form?.message} + {form?.message} + {/if} + +
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 @@ +

Logged in!

diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js new file mode 100644 index 000000000..369fcce46 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/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/03-named-form-actions/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..9d9760c5e --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte @@ -0,0 +1,16 @@ + + +

Please log in

+ +
+ + + {#if form?.message} + {form?.message} + {/if} + + +
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 `
` we have built works completely without JavaScript - which is great! If we have JavaScript enabled though ([which may be less often than you think](https://kryogenix.org/code/browser/everyonehasjs.html)), we can provide a better user experience by not reloading the whole page, showing loading animations, and more. + +The easiest way to progressively enhance our `` is to add the `enhance` action to it: + +```svelte + + + + + + {#if form?.message} + {form?.message} + {/if} + + +
+``` + +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
, form and $page will not be updated. This is because in the native form submission case you would be redirected to the page the action is on. +- invalidate all data on a successful response +- navigate to the new page on a redirect response +- render the nearest error page if an error occurs diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js new file mode 100644 index 000000000..369fcce46 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/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/04-progressive-enhancement/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..9d9760c5e --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte @@ -0,0 +1,16 @@ + + +

Please log in

+ + + + + {#if form?.message} + {form?.message} + {/if} + + +
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 @@ +

Logged in!

diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..0d38015c1 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte @@ -0,0 +1,17 @@ + + +

Please log in

+ +
+ + + {#if form?.message} + {form?.message} + {/if} + + +
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 `
` by adding the `enhance` action to it, which enables the native form behavior just without the full page reload. We can further customize the submission experience by adding a custom callback to the `enhance` action. Let's do that by disabling the buttons while an action is in progress: + +```svelte + + + { + submitting = true; + return async ({ update }) => { + await update(); + submitting = false; + } +}}+++> + + + {#if form?.message} + {form?.message} + {/if} + + +
+``` + +`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 @@ + + +

Please log in

+ +
+ + + {#if form?.message} + {form?.message} + {/if} + + +
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/user/+page.svelte new file mode 100644 index 000000000..15c324713 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-a/src/routes/user/+page.svelte @@ -0,0 +1 @@ +

Logged in!

diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..fd9fb644b --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte @@ -0,0 +1,32 @@ + + +

Please log in

+ +
{ + submitting = true; + return async ({ update }) => { + await update(); + submitting = false; + }; + }} +> + + + {#if form?.message} + {form?.message} + {/if} + + +
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 `
` elements. For these cases, you can use the `+server.js` endpoints we learned about in the previous chapter for data mutation. + +TODO good example diff --git a/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..1333ed77b --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +TODO diff --git a/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..1333ed77b --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/06-mutation-through-endpoints/app-b/src/routes/+page.svelte @@ -0,0 +1 @@ +TODO From 99e07e18e12f4bdb6321be49f49d57715aee036d Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:20:57 +0200 Subject: [PATCH 006/177] Apply suggestions from code review Co-authored-by: Tan Li Hau --- .../02-sveltekit/02-routing/03-loading-data/README.md | 6 ++++-- .../02-routing/04-loading-layout-data/README.md | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) 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 index abdddd1ac..29d1fc3f3 100644 --- a/content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md +++ b/content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md @@ -2,13 +2,15 @@ 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. +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. You could do this with a regular `fetch` inside `onMount`. However, that doesn't work with server-side-rendering or prerendering, and you'd end up with half-finished pages that load 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`. +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 make sure it works the same way in the client and server, use the `fetch` function passed into `load` to fetch 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`: 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 index a023c6a3f..024c55170 100644 --- 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 @@ -6,7 +6,7 @@ Layouts can provide common UI across pages. They can also provide common data ac 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`. +This `load` function works the same as the `load` function in `+page.js`. 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`: From b3112ad5d90094b80bd4989cd117d03cdb2de89c Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 21 Oct 2022 16:31:54 +0200 Subject: [PATCH 007/177] errors and redirects chapter --- .../01-error-pages/README.md | 9 ++++ .../app-a/src/routes/+layout.svelte | 6 +++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/about/+error.svelte | 1 + .../app-a/src/routes/about/+page.js | 3 ++ .../app-a/src/routes/about/+page.svelte | 4 ++ .../02-custom-error-messages/README.md | 52 +++++++++++++++++++ .../app-a/src/app.d.ts | 1 + .../app-a/src/hooks.client.js | 3 ++ .../app-a/src/hooks.server.js | 3 ++ .../app-a/src/routes/+layout.svelte | 6 +++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/about/+error.svelte | 1 + .../app-a/src/routes/about/+page.js | 3 ++ .../app-a/src/routes/about/+page.svelte | 4 ++ .../app-b/src/hooks.client.js | 3 ++ .../app-b/src/hooks.server.js | 3 ++ .../app-b/src/routes/about/+error.svelte | 7 +++ .../app-b/src/routes/about/+page.js | 3 ++ .../03-expected-errors/README.md | 20 +++++++ .../app-a/src/routes/+layout.svelte | 6 +++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/about/+error.svelte | 7 +++ .../app-a/src/routes/about/+page.js | 3 ++ .../app-a/src/routes/about/+page.svelte | 4 ++ .../app-b/src/routes/about/+page.js | 5 ++ .../04-redirects/README.md | 19 +++++++ .../app-a/src/routes/+layout.svelte | 7 +++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/login/+page.js | 1 + .../app-a/src/routes/login/+page.svelte | 1 + .../app-a/src/routes/user/+page.svelte | 1 + .../app-b/src/routes/login/+page.js | 6 +++ 33 files changed, 196 insertions(+) create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/app.d.ts create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.client.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.server.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+error.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.client.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.server.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+error.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+error.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-b/src/routes/about/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.js create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/user/+page.svelte create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-b/src/routes/login/+page.js diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md new file mode 100644 index 000000000..300ef0e39 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md @@ -0,0 +1,9 @@ +--- +title: Error Pages +--- + +If something goes wrong during executing the `load` functions for a page, we can "catch" these errors with `+error.svelte` pages. + +For teaching purposes, we created a `+page.js` `load` function which throws an error. That error will bubble up the file tree until it finds a `+error.svelte` or falls back to a generic error page if there's none. In this example we placed one right next to the erroring `+page.js` - notice how the outer layout still renders and keeps the app functioning. + +Inside `+error.svelte`, you are free to put any content you like. Just play around with it a little! diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..8a38e3a9a --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+layout.svelte @@ -0,0 +1,6 @@ + + + diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..68002cd17 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Welcome

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte new file mode 100644 index 000000000..736d1d2d5 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte @@ -0,0 +1 @@ +

On no, something went wrong!

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.js new file mode 100644 index 000000000..7985fbf13 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.js @@ -0,0 +1,3 @@ +export function load() { + throw new Error('boom'); +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.svelte new file mode 100644 index 000000000..934797c93 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+page.svelte @@ -0,0 +1,4 @@ +

+ This is the best about page of all time. Sad + that you'll never see it because of the error. +

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md new file mode 100644 index 000000000..970ab5584 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md @@ -0,0 +1,52 @@ +--- +title: Customizing the error message +--- + +The error page in the previous section is rather static. Maybe you want to show the error message so you can help people turning up in your support channels faster. + +For this, SvelteKit provides you with `$page.error` and `$page.status`, which contain information about the error and the status code. Let's add it to `+error.svelte`: + +```svelte +++++++ +

{$page.status}

+

On no, something went wrong!

++++

{$page.error.message}

+``` + +That's better, but `$page.error.message` always contains "Internal Error" - how so? This is because SvelteKit plays it safe and prevents you from accidentally showing sensitive information as part of the error message. + +To customize it, we implement the `handleError` hook in `hooks.server.js` and `hooks.client.js` which run when an unexpected error is thrown during data loads on the server or client respectively. + +```js +// hooks.server.js +export function handleError(+++{ error }+++) { + ---return { message: 'Internal Error' }; // the default implementation of this hook--- + +++return { message: error instanceof Error ? error.message : 'Internal Error' };+++ +} +``` + +```js +// hooks.client.js +export function handleError(+++{ error }+++) { + ---return { message: 'Internal Error' }; // the default implementation of this hook--- + +++return { message: error instanceof Error ? error.message : 'Internal Error' };+++ +} +``` + +You could also call your error reporting service in these hooks. + +Note that you can return more than an error message if you like. Whatever object shape you return will be available in `$page.error`, the only requirement is a `message` property. You can even make it type-safe by typing the error object inside `app.d.ts` be defining an `Error` interface with the right shape: + +```js +// app.d.ts +declare namespace App { + interface Error { + message: string; + somethingElse: number; + } +} +``` + +> When handling errors, be careful to not assume it's an `Error` object, anything could be thrown. Also make sure not to expose senstive data by forwarding too much information diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/app.d.ts b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/app.d.ts new file mode 100644 index 000000000..4b888cdd7 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/app.d.ts @@ -0,0 +1 @@ +declare namespace App {} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.client.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.client.js new file mode 100644 index 000000000..62a95696f --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.client.js @@ -0,0 +1,3 @@ +export function handleError() { + return { message: 'Internal Error' }; // the default implementation of this hook +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.server.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.server.js new file mode 100644 index 000000000..62a95696f --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/hooks.server.js @@ -0,0 +1,3 @@ +export function handleError() { + return { message: 'Internal Error' }; // the default implementation of this hook +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..8a38e3a9a --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+layout.svelte @@ -0,0 +1,6 @@ + + + diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..68002cd17 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Welcome

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+error.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+error.svelte new file mode 100644 index 000000000..736d1d2d5 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+error.svelte @@ -0,0 +1 @@ +

On no, something went wrong!

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.js new file mode 100644 index 000000000..7985fbf13 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.js @@ -0,0 +1,3 @@ +export function load() { + throw new Error('boom'); +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.svelte new file mode 100644 index 000000000..934797c93 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-a/src/routes/about/+page.svelte @@ -0,0 +1,4 @@ +

+ This is the best about page of all time. Sad + that you'll never see it because of the error. +

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.client.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.client.js new file mode 100644 index 000000000..5057ad2af --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.client.js @@ -0,0 +1,3 @@ +export function handleError({ error }) { + return { message: error instanceof Error ? error.message : 'Internal Error' }; +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.server.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.server.js new file mode 100644 index 000000000..5057ad2af --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/hooks.server.js @@ -0,0 +1,3 @@ +export function handleError({ error }) { + return { message: error instanceof Error ? error.message : 'Internal Error' }; +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+error.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+error.svelte new file mode 100644 index 000000000..deea7ad46 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+error.svelte @@ -0,0 +1,7 @@ + + +

{$page.status}

+

On no, something went wrong!

+

{$page.error.message}

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+page.js new file mode 100644 index 000000000..7985fbf13 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/app-b/src/routes/about/+page.js @@ -0,0 +1,3 @@ +export function load() { + throw new Error('boom'); +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md new file mode 100644 index 000000000..3ca607098 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md @@ -0,0 +1,20 @@ +--- +title: Expected errors +--- + +You can also throw _expected_ errors, for example when your app is ending up in an illegal state. For this, use `error` from `@sveltejs/kit`. + +Its first argument is the status code, the second is the error message. Let's use that to adjust our `load` function in `+page.js`. + +```js ++++import { error } from '@sveltejs/kit';+++ + +export function load() { + ---throw new Error('boom');--- + +++throw error(403, "I changed my mind, I don't want you to see this");+++ +} +``` + +In contrast to unexpected error, the message of `error`s you throw yourself this way do _not_ call the `handleError` hook and are propagated to `$page.error` directly. + +> If you defined the error shape through the `App.Error` interface, the second parameter passed to the `error` function expects this shape. diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..8a38e3a9a --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+layout.svelte @@ -0,0 +1,6 @@ + + + diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..68002cd17 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Welcome

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+error.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+error.svelte new file mode 100644 index 000000000..deea7ad46 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+error.svelte @@ -0,0 +1,7 @@ + + +

{$page.status}

+

On no, something went wrong!

+

{$page.error.message}

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.js new file mode 100644 index 000000000..7985fbf13 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.js @@ -0,0 +1,3 @@ +export function load() { + throw new Error('boom'); +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.svelte new file mode 100644 index 000000000..934797c93 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-a/src/routes/about/+page.svelte @@ -0,0 +1,4 @@ +

+ This is the best about page of all time. Sad + that you'll never see it because of the error. +

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-b/src/routes/about/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-b/src/routes/about/+page.js new file mode 100644 index 000000000..1afd9ff36 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/app-b/src/routes/about/+page.js @@ -0,0 +1,5 @@ +import { error } from '@sveltejs/kit'; + +export function load() { + throw error(403, "I changed my mind, I don't want you to see this"); +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md new file mode 100644 index 000000000..0acf06666 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md @@ -0,0 +1,19 @@ +--- +title: Redirects +--- + +Besides errors there's one more thing you can `throw`, and that's `redirect`s. + +Let's use that navigate away from our login page when we're logged in. + +```js +// login/+page.js ++++import { redirect } from '@sveltejs/kit';+++ + +export function load() { + // let's assume for simplicity we are always logged in + +++throw redirect(307, '/user');+++ +} +``` + +> You may remember this function from the form actions chapter, where it was used to navigate to the user page after a successful login diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..a3cde344d --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+layout.svelte @@ -0,0 +1,7 @@ + + + diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..68002cd17 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Welcome

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.js new file mode 100644 index 000000000..23addb029 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.js @@ -0,0 +1 @@ +export function load() {} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.svelte new file mode 100644 index 000000000..bb59e7545 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/login/+page.svelte @@ -0,0 +1 @@ +

Login

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/user/+page.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/user/+page.svelte new file mode 100644 index 000000000..d1a8e69c3 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-a/src/routes/user/+page.svelte @@ -0,0 +1 @@ +

User page

diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-b/src/routes/login/+page.js b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-b/src/routes/login/+page.js new file mode 100644 index 000000000..eda500fd1 --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/app-b/src/routes/login/+page.js @@ -0,0 +1,6 @@ +import { redirect } from '@sveltejs/kit'; + +export function load() { + // let's assume for simplicity we are always logged in + throw redirect(307, '/user'); +} From c46b15b9ba3f9bd2dad5ebde278cc235a18504c4 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 25 Oct 2022 10:06:49 +0200 Subject: [PATCH 008/177] invalidation chapter --- .../05-invalidation/01-refresh-data/README.md | 36 ++++++++++++++++++ .../01-refresh-data/app-a/src/routes/+page.js | 1 + .../app-a/src/routes/+page.svelte | 3 ++ .../app-a/src/routes/api/clock/+server.js | 5 +++ .../01-refresh-data/app-b/src/routes/+page.js | 4 ++ .../app-b/src/routes/+page.svelte | 15 ++++++++ .../02-custom-data-dependencies/README.md | 36 ++++++++++++++++++ .../app-a/src/routes/+page.js | 4 ++ .../app-a/src/routes/+page.svelte | 15 ++++++++ .../app-a/src/routes/api/clock/+server.js | 5 +++ .../app-b/src/routes/+page.js | 6 +++ .../app-b/src/routes/+page.svelte | 15 ++++++++ .../03-refresh-all-data/README.md | 38 +++++++++++++++++++ .../app-a/src/routes/+page.js | 6 +++ .../app-a/src/routes/+page.svelte | 15 ++++++++ .../app-b/src/routes/+page.js | 5 +++ .../app-b/src/routes/+page.svelte | 15 ++++++++ 17 files changed, 224 insertions(+) create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/api/clock/+server.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/api/clock/+server.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md create mode 100644 content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md new file mode 100644 index 000000000..4867624e5 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md @@ -0,0 +1,36 @@ +--- +title: Refreshing data +--- + +When SvelteKit navigates to a site, it runs the related `load` functions. After some time, that data might become stale, so we want to refresh it. This is possible using `invalidate` or `invalidateAll`. + +Let's start with `invalidate`. You call it inside a component with a `url`. All `load` functions that have a dependency on this `url` will then be rerun. This works nicely in combination with `fetch`, which registers the `url` as a dependency of the `load` function. + +Let's get the clock in our example ticking by first fetching some data in `+page.js`... + +```js +export async function load({ fetch }) { + +++const response = await fetch('/api/clock'); + return response.json();+++ +} +``` + +...and refreshing that data every second inside our component by using `invalidate` and passing the same `url` we passed to `fetch`. + +```svelte + + +
{data.time}
+``` + +> You can also pass a function to `invalidate`, in case you want to invalidate based on a pattern and not specific URLs diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.js new file mode 100644 index 000000000..9f617ec04 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.js @@ -0,0 +1 @@ +export async function load({ fetch }) {} diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..e6e9ef8cd --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte @@ -0,0 +1,3 @@ + diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/api/clock/+server.js b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/api/clock/+server.js new file mode 100644 index 000000000..aaefa8f4c --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/api/clock/+server.js @@ -0,0 +1,5 @@ +import { json } from '@sveltejs/kit'; + +export function GET() { + return json({ time: new Date().toLocaleTimeString() }); +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.js new file mode 100644 index 000000000..e7486bf66 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.js @@ -0,0 +1,4 @@ +export async function load({ fetch }) { + const response = await fetch('/api/clock'); + return response.json(); +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..334668ffd --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte @@ -0,0 +1,15 @@ + + +
{data.time}
diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md new file mode 100644 index 000000000..f871b18e1 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md @@ -0,0 +1,36 @@ +--- +title: Custom data dependencies +--- + +Sometimes you can't or don't want to get data using `fetch`, which means that there's no `url` registered automatically as a `load` dependency which you could `invalidate`. In this case, use `depends` to register a `url` manually. + +Did you know that `foo:bar` is a valid `url`? We can use this to our advantage to create valid custom `url`s that are readable. Let's do that to move our "calculation" of the current time into the `load` function: + +```js +export async function load({ ---fetch---+++depends+++ }) { + ---const response = await fetch('/api/clock'); + return response.json();--- + +++depends('tick:tock'); + return { + time: new Date().toLocaleTimeString() + };+++ +} +``` + +```svelte + + +
{data.time}
+``` diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.js new file mode 100644 index 000000000..e7486bf66 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.js @@ -0,0 +1,4 @@ +export async function load({ fetch }) { + const response = await fetch('/api/clock'); + return response.json(); +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..334668ffd --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte @@ -0,0 +1,15 @@ + + +
{data.time}
diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/api/clock/+server.js b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/api/clock/+server.js new file mode 100644 index 000000000..aaefa8f4c --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/api/clock/+server.js @@ -0,0 +1,5 @@ +import { json } from '@sveltejs/kit'; + +export function GET() { + return json({ time: new Date().toLocaleTimeString() }); +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.js new file mode 100644 index 000000000..30aa1713d --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.js @@ -0,0 +1,6 @@ +export async function load({ depends }) { + depends('tick:tock'); + return { + time: new Date().toLocaleTimeString() + }; +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..a1a2ef68e --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte @@ -0,0 +1,15 @@ + + +
{data.time}
diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md new file mode 100644 index 000000000..e89066f81 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md @@ -0,0 +1,38 @@ +--- +title: Refresh all data +--- + +Sometimes you want to refresh all data across the site, regardless of any `url` dependencies. For this, use `invalidateAll`. + +Let's use `invalidateAll` in our clock example. First we'll update the component: + +```svelte + + +
{data.time}
+``` + +Since `invalidateAll` runs _all_ `load` functions regardless of their `url` dependencies, we can simplify the code in `+page.js` by removing the `depends` call: + +```js +export async function load(---{ depends }---) { + ---depends('tick:tock');--- + return { + time: new Date().toLocaleTimeString() + }; +} +``` + +> `invalidate(() => true)` and `invalidateAll` are _not_ the same. `invalidateAll` also reruns `load` functions without any `url` dependencies, which `invalidate(() => true)` wouldn't diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.js new file mode 100644 index 000000000..30aa1713d --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.js @@ -0,0 +1,6 @@ +export async function load({ depends }) { + depends('tick:tock'); + return { + time: new Date().toLocaleTimeString() + }; +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..a1a2ef68e --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte @@ -0,0 +1,15 @@ + + +
{data.time}
diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.js new file mode 100644 index 000000000..02e6af4dc --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.js @@ -0,0 +1,5 @@ +export async function load() { + return { + time: new Date().toLocaleTimeString() + }; +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..c55b64da7 --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte @@ -0,0 +1,15 @@ + + +
{data.time}
From 5401f33df23e5a5a7c3029ad858823f786278da3 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 25 Oct 2022 12:10:50 +0200 Subject: [PATCH 009/177] render options section --- .../01-rendering-options-basics/README.md | 13 +++++++++++++ .../app-a/src/routes/+page.js | 1 + .../app-a/src/routes/+page.svelte | 1 + .../06-rendering-options/02-ssr/README.md | 9 +++++++++ .../02-ssr/app-a/src/routes/+page.js | 0 .../02-ssr/app-a/src/routes/+page.svelte | 3 +++ .../06-rendering-options/03-csr/README.md | 13 +++++++++++++ .../03-csr/app-a/src/routes/+page.js | 0 .../03-csr/app-a/src/routes/+page.svelte | 5 +++++ .../03-csr/app-b/src/routes/+page.js | 1 + .../06-rendering-options/04-prerender/README.md | 17 +++++++++++++++++ .../04-prerender/app-a/src/routes/+page.js | 5 +++++ .../04-prerender/app-a/src/routes/+page.svelte | 7 +++++++ .../04-prerender/app-b/src/routes/+page.js | 7 +++++++ 14 files changed, 82 insertions(+) create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/03-csr/README.md create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-b/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.js create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-b/src/routes/+page.js diff --git a/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md new file mode 100644 index 000000000..4442d70c2 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md @@ -0,0 +1,13 @@ +--- +title: Rendering Options Basics +--- + +SvelteKit let's you customize when and how pages are rendered. + +By default, SvelteKit will render (or prerender) any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called hydration. For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a router that takes over subsequent navigations. + +You can control each of these on a page-by-page basis by exporting options from `+page.js` or `+page.server.js`, or for groups of pages using a shared `+layout.js` or `+layout`. To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered. + +You can mix and match these options in different areas of your app. For example you could prerender your marketing page for maximum speed, server-render your dynamic pages for SEO and accessibility and turn your admin section into an SPA by rendering it on the client only. This makes SvelteKit very versatile. + +Let's look at each of these option by example in the following sections. diff --git a/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.js new file mode 100644 index 000000000..84d3da884 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.js @@ -0,0 +1 @@ +// You can add the options in this file, or `+page.server.js`, or their corresponding layout files diff --git a/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..b0144bb62 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Prerendering options

diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md new file mode 100644 index 000000000..7e817f634 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md @@ -0,0 +1,9 @@ +--- +title: Server Side Rendering +--- + +The `ssr` option controls whether or not a page is rendered on the server. + +By default this option is set to `true`. Setting this option to `false` will make the page render on the client only - if you enable it for your whole app, you've turned it into an SPA. + +Setting it to `false` is useful if you have things on your page that should not or even cannot run on the server. TODO good example diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.js new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..e6e9ef8cd --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte @@ -0,0 +1,3 @@ + diff --git a/content/tutorial/02-sveltekit/06-rendering-options/03-csr/README.md b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/README.md new file mode 100644 index 000000000..5fed712c8 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/README.md @@ -0,0 +1,13 @@ +--- +title: Client Side Rendering +--- + +The `csr` option controls whether or not a page is rendered on the client. + +By default this option is set to `true`. Setting this option to `false` will make the page render on the server only - which means 0kb of JS! + +Setting it to `false` is useful if you have pages that don't have any interactivity requirements such as a static about page. Let's add this option to ours inside `+page.js`: + +```js ++++export const csr = false;+++ +``` diff --git a/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.js new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..9eb58c2ba --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-a/src/routes/+page.svelte @@ -0,0 +1,5 @@ +

Turning CSR off

+ +

+ Static sites don't need any JS, so why ship it? +

diff --git a/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-b/src/routes/+page.js new file mode 100644 index 000000000..26bb56887 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/03-csr/app-b/src/routes/+page.js @@ -0,0 +1 @@ +export const csr = false; diff --git a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md new file mode 100644 index 000000000..7ef474026 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md @@ -0,0 +1,17 @@ +--- +title: Prerendering +--- + +The `prerender` option controls whether a page is rendered at build time or at runtime. + +By default this option is set to `false`. Setting this option to `true` will render the page into a good ol' HTML file at build time. + +Setting it to `true` is useful if you have pages that don't have any dependency on runtime data such as a static about page. Let's add this option to ours inside `+page.js`: + +```js ++++export const prerender = true;+++ +``` + +To really see this in effect, you'd need to run the build step, which we can't in this tutorial. + +> If you set `prerender` to `true` inside your root `+layout.js`, you turn SvelteKit into a static site generator! diff --git a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.js new file mode 100644 index 000000000..57ed1f06b --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.js @@ -0,0 +1,5 @@ +export function load() { + return { + text: `This site doesn't depend on any dynamic data, so why not prerender it?` + }; +} diff --git a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..408541df8 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-a/src/routes/+page.svelte @@ -0,0 +1,7 @@ + + +

Enable Prerendering

+ +

{data.text}

diff --git a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-b/src/routes/+page.js new file mode 100644 index 000000000..6a584d03d --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/app-b/src/routes/+page.js @@ -0,0 +1,7 @@ +export const prerender = true; + +export function load() { + return { + text: `This site doesn't depend on any dynamic data, so why not prerender it?` + }; +} From db092ba36c155ad4c66339a5869b8599c48b42b3 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 25 Oct 2022 12:20:48 +0200 Subject: [PATCH 010/177] add missing meta.json files --- content/tutorial/02-sveltekit/03-mutating-data/meta.json | 3 +++ .../tutorial/02-sveltekit/04-errors-and-redirects/meta.json | 3 +++ content/tutorial/02-sveltekit/05-invalidation/meta.json | 3 +++ content/tutorial/02-sveltekit/06-rendering-options/meta.json | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 content/tutorial/02-sveltekit/03-mutating-data/meta.json create mode 100644 content/tutorial/02-sveltekit/04-errors-and-redirects/meta.json create mode 100644 content/tutorial/02-sveltekit/05-invalidation/meta.json create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/meta.json diff --git a/content/tutorial/02-sveltekit/03-mutating-data/meta.json b/content/tutorial/02-sveltekit/03-mutating-data/meta.json new file mode 100644 index 000000000..1771eb885 --- /dev/null +++ b/content/tutorial/02-sveltekit/03-mutating-data/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Mutating Data" +} diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/meta.json b/content/tutorial/02-sveltekit/04-errors-and-redirects/meta.json new file mode 100644 index 000000000..1e073db3c --- /dev/null +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Errors And Redirects" +} diff --git a/content/tutorial/02-sveltekit/05-invalidation/meta.json b/content/tutorial/02-sveltekit/05-invalidation/meta.json new file mode 100644 index 000000000..caf2754cc --- /dev/null +++ b/content/tutorial/02-sveltekit/05-invalidation/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Invalidation" +} diff --git a/content/tutorial/02-sveltekit/06-rendering-options/meta.json b/content/tutorial/02-sveltekit/06-rendering-options/meta.json new file mode 100644 index 000000000..dcab69491 --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Rendering Options" +} From ddde6b46c3aa75d047ac5e200617f4220c0d6258 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 15 Nov 2022 16:34:44 +0100 Subject: [PATCH 011/177] advanced routing wip --- .../01-optional-params/README.md | 7 +++++++ .../app-a/src/routes/+layout.svelte | 6 ++++++ .../app-a/src/routes/+page.svelte | 1 + .../src/routes/[[optional]]/home/+page.svelte | 8 +++++++ .../02-rest-params/README.md | 21 +++++++++++++++++++ .../app-a/src/routes/+error.svelte | 3 +++ .../app-a/src/routes/+layout.svelte | 7 +++++++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/[...rest]/+page.js} | 0 .../app-b/src/routes/[...rest]/+page.js | 5 +++++ .../03-layout-groups/README.md | 11 ++++++++++ .../app-a/src/routes/+layout.svelte | 16 ++++++++++++++ .../app-a/src/routes/+page.svelte | 3 +++ .../app-a/src/routes/about/+page.svelte | 17 +++++++++++++++ .../app-a/src/routes/pricing/+page.svelte | 3 +++ .../src/routes/(marketing)/+layout.svelte | 3 +++ .../app-b/src/routes/(marketing)/+page.svelte | 3 +++ .../routes/(marketing)/pricing/+page.svelte | 3 +++ .../app-b/src/routes/+layout.svelte | 16 ++++++++++++++ .../app-b/src/routes/about/+page.svelte | 3 +++ .../01-advanced-routing/meta.json | 3 +++ .../01-todo/01-sandbox/README.md | 5 ----- .../app-a/node_modules/cjs-dep/index.js | 9 -------- .../app-a/node_modules/cjs-dep/package.json | 3 --- .../app-a/node_modules/esm-dep/index.js | 1 - .../app-a/node_modules/esm-dep/package.json | 3 --- .../01-todo/01-sandbox/app-a/src/lib/b.js | 3 --- .../01-sandbox/app-a/src/routes/+page.svelte | 1 - .../01-todo/01-sandbox/app-a/svelte.config.js | 10 --------- .../01-todo/01-sandbox/app-a/vite.config.js | 6 ------ .../04-advanced-sveltekit/01-todo/meta.json | 3 --- 31 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+page.svelte rename content/tutorial/04-advanced-sveltekit/{01-todo/01-sandbox/app-a/src/lib/a.js => 01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js} (100%) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/meta.json delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/README.md delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/index.js delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/package.json delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/index.js delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/package.json delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/b.js delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/routes/+page.svelte delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/svelte.config.js delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/vite.config.js delete mode 100644 content/tutorial/04-advanced-sveltekit/01-todo/meta.json diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md new file mode 100644 index 000000000..cadea7828 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md @@ -0,0 +1,7 @@ +--- +title: Optional Parameters +--- + +A route like `[lang]/home` contains a parameter named `lang` which is required. Sometimes it's beneficial to make these parameters optional, so that in this example both `home` and `en/home` point to the same page. You can do that by using optional parameters. + +An optional parameter looks like a required parameter with one more bracket pair around it: `[[optional]]`. The variable name inside - in this case `optional` - is available to the `load` function through the `params` object and also through the `$page.params` store. diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..45ec290f2 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte @@ -0,0 +1,6 @@ +

+ Go to the default home page. +

+

+ Go to the english home page. +

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..f95bef307 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Home

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte new file mode 100644 index 000000000..9250fd499 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte @@ -0,0 +1,8 @@ + + +

+ Welcome to the {$page.params.optional ?? + 'default'} home page +

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md new file mode 100644 index 000000000..e8e2281ed --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md @@ -0,0 +1,21 @@ +--- +title: Rest Parameters +--- + +The number of route segments might be unknown sometimes. Other times, you might want to have a catch-all route for everything that wasn't already matched to another route. For these use cases, use rest parameters. + +Rest parameters look like an array spread: `[...rest]`. The variable name inside - in this case `rest` - is available to the `load` function through the `params` object and also through the `$page.params` store. + +Let's use this rest parameter to implement a catch-all route to redirect to our nice-look error page instead. Add the following to `[...rest]/+page.js`: + +```js ++++import { error } from '@sveltejs/kit'; + +export function load() { + throw error(404, 'Page not found'); +}+++ +``` + +Now, when the user ends up on a route that isn't know to the app, the catch-all route will be matched, throwing the error, which means we end up on `+error.svelte`. + +> This is the recommended pattern for implementing your own 404 page diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte new file mode 100644 index 000000000..803d46d09 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte @@ -0,0 +1,3 @@ +

404

+ +

Page not found

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..84d573522 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte @@ -0,0 +1,7 @@ +

+ Go to the home page. +

+

+ Go to a non-existing + page. +

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..f95bef307 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Home

diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/a.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/a.js rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js 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 new file mode 100644 index 000000000..e335d6c3d --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-b/src/routes/[...rest]/+page.js @@ -0,0 +1,5 @@ +import { error } from '@sveltejs/kit'; + +export function load() { + throw error(404, 'Page not found'); +} diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md new file mode 100644 index 000000000..62a02f31c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md @@ -0,0 +1,11 @@ +--- +title: Layout Groups +--- + +Sections of your app often share a common UI. To not repeat that code, we can use layouts. These form a hierarchy, a page inherits all layouts above it. Sometimes it's necessary to break out of this hierarchy. For this, we can use layout groups. + +In this example we have three pages — the home page, the about page, and a pricing page. The home and pricing page should both have a marketing layout, the about page should not. All three pages are at the same level, so we can't put a common layout for the home and pricing page in the route hierarchy. Instead, we add a group. + +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`. + +TODO how to do a before/after when we don't have a way to create files? Should we have one? diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..9c47bb66c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..ca3ffb790 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte @@ -0,0 +1,3 @@ +

Home

+ +

This is the home page.

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte new file mode 100644 index 000000000..17363fd17 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte @@ -0,0 +1,17 @@ + + +

About

+ +

This is the about page.

+ + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte new file mode 100644 index 000000000..2190eb268 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte @@ -0,0 +1,3 @@ +

Pricing

+ +

This is the pricing page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte new file mode 100644 index 000000000..2dc175c65 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte @@ -0,0 +1,3 @@ +
Marketing Layout
+ + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte new file mode 100644 index 000000000..ca3ffb790 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte @@ -0,0 +1,3 @@ +

Home

+ +

This is the home page.

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte new file mode 100644 index 000000000..2190eb268 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte @@ -0,0 +1,3 @@ +

Pricing

+ +

This is the pricing page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte new file mode 100644 index 000000000..9c47bb66c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte new file mode 100644 index 000000000..212bd68ff --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte @@ -0,0 +1,3 @@ +

About

+ +

This is the about page.

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/meta.json b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/meta.json new file mode 100644 index 000000000..8e1dafef5 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Advanced Routing" +} diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/README.md b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/README.md deleted file mode 100644 index dd6c3a722..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/README.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Sandbox ---- - -ignore me diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/index.js b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/index.js deleted file mode 100644 index 281fec0c3..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/index.js +++ /dev/null @@ -1,9 +0,0 @@ -// line 1 -// line 2 -// line 2 -// line 2 -// line 2 -// line 2 -// line 2 -// line 2 -module.exports = () => 'wooo!!! cjs'; \ No newline at end of file diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/package.json b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/package.json deleted file mode 100644 index a2091cee3..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/cjs-dep/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} \ No newline at end of file diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/index.js b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/index.js deleted file mode 100644 index 38e1306fd..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/index.js +++ /dev/null @@ -1 +0,0 @@ -export default () => 'wooo!!! esm'; \ No newline at end of file diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/package.json b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/package.json deleted file mode 100644 index 47dc78d39..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/node_modules/esm-dep/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} \ No newline at end of file diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/b.js b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/b.js deleted file mode 100644 index 7b9db73a0..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/lib/b.js +++ /dev/null @@ -1,3 +0,0 @@ -export function foo() { - return 42; -} diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/routes/+page.svelte deleted file mode 100644 index 1afc09501..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/src/routes/+page.svelte +++ /dev/null @@ -1 +0,0 @@ -

sandbox

diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/svelte.config.js b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/svelte.config.js deleted file mode 100644 index 301e785eb..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/svelte.config.js +++ /dev/null @@ -1,10 +0,0 @@ -import adapter from '@sveltejs/adapter-auto'; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - kit: { - adapter: adapter() - } -}; - -export default config; diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/vite.config.js b/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/vite.config.js deleted file mode 100644 index da06c515e..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/01-sandbox/app-a/vite.config.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('vite').UserConfig} */ -export default { - optimizeDeps: { - include: ['cjs-dep'] - } -}; diff --git a/content/tutorial/04-advanced-sveltekit/01-todo/meta.json b/content/tutorial/04-advanced-sveltekit/01-todo/meta.json deleted file mode 100644 index 20a00a555..000000000 --- a/content/tutorial/04-advanced-sveltekit/01-todo/meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "title": "TODO" -} From b498e13192b2591331a0160666ab9fee8e340345 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 18 Nov 2022 12:19:19 +0100 Subject: [PATCH 012/177] fix link --- .../01-svelte/01-introduction/01-welcome-to-svelte/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md b/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md index 334208c98..3f99d8138 100644 --- a/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md +++ b/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md @@ -25,7 +25,7 @@ This tutorial is split into four main parts: - [Welcome to Svelte](/tutorial/welcome-to-svelte) (you are here) - [Introduction to SvelteKit](/tutorial/introducing-sveltekit) - [Advanced Svelte](/tutorial/tweens) -- [Advanced SvelteKit](/tutorial/sandbox) +- [Advanced SvelteKit](/tutorial/optional-params) Each section will present an exercise designed to illustrate a feature. Later sections build on the knowledge gained in earlier ones, so it's recommended that you go from start to finish. If necessary, you can navigate via the menu above. From 0593cd9d0afc152f17825e94f1b39409d253f6c8 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 25 Nov 2022 10:48:21 +0100 Subject: [PATCH 013/177] matching, groups --- .../03-param-matchers/README.md | 45 +++++++++++++++++++ .../app-a/src/routes/+layout.svelte | 18 ++++++++ .../app-a/src/routes/+page.svelte | 1 + .../src/routes/archive/[page]/+page.svelte | 1 + .../app-b/src/params/integer.js | 3 ++ .../archive/[page=integer]/+page.svelte | 1 + .../README.md | 17 ++++++- .../app-a/src/routes/+layout.svelte | 0 .../app-a/src/routes/+page.svelte | 0 .../app-a/src/routes/about/+page.svelte | 0 .../app-a/src/routes/pricing/+page.svelte | 0 .../src/routes/(marketing)/+layout.svelte | 0 .../app-b/src/routes/(marketing)/+page.svelte | 0 .../routes/(marketing)/pricing/+page.svelte | 0 .../app-b/src/routes/+layout.svelte | 0 .../app-b/src/routes/about/+page.svelte | 0 .../05-breaking-out-of-layouts/README.md | 24 ++++++++++ .../app-a/src/routes/+layout.svelte | 7 +++ .../app-a/src/routes/+page.svelte | 1 + .../app-a/src/routes/business/+layout.svelte | 2 + .../app-a/src/routes/business/+page.svelte | 1 + .../routes/business/pricing/+layout.svelte | 2 + .../src/routes/business/pricing/+page.svelte | 1 + .../app-b/src/business/pricing/+page@.svelte | 1 + 24 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/archive/[page]/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/params/integer.js create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page=integer]/+page.svelte rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/README.md (56%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-a/src/routes/+layout.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-a/src/routes/+page.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-a/src/routes/about/+page.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-a/src/routes/pricing/+page.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-b/src/routes/(marketing)/+layout.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-b/src/routes/(marketing)/+page.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-b/src/routes/(marketing)/pricing/+page.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-b/src/routes/+layout.svelte (100%) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/{03-layout-groups => 04-layout-groups}/app-b/src/routes/about/+page.svelte (100%) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+layout.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte 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 new file mode 100644 index 000000000..bcc468e49 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md @@ -0,0 +1,45 @@ +--- +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: + +```diff +src/ +├ params/ ++│ └ integer.js +├ routes/ +│ ├ archive/ +│ │ ├ [page]/ +│ │ │ └ +page.svelte +│ ├ +layout.svelte +│ └ +page.svelte +``` + +```js +// src/params/integer.js ++++export function match(param) { + return /^\d+$/.test(param); +}+++ +``` + +Then augment your routes with the matcher: + +```diff +src/ +├ params/ +│ └ integer.js +├ routes/ +│ ├ archive/ +-│ │ ├ [page]/ ++│ │ ├ [page=integer]/ +│ │ │ └ +page.svelte +│ ├ +layout.svelte +│ └ +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. + +> Matchers run both on the server and in the browser. diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..6be286f61 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+layout.svelte @@ -0,0 +1,18 @@ + + + + +
+Page Params:
+{JSON.stringify($page.params, null, 2)}
+
+ + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..e5324dcb6 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Home Page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/archive/[page]/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/archive/[page]/+page.svelte new file mode 100644 index 000000000..df3a52fdf --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-a/src/routes/archive/[page]/+page.svelte @@ -0,0 +1 @@ +

Archive Page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/params/integer.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/params/integer.js new file mode 100644 index 000000000..d3f8efdf2 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/params/integer.js @@ -0,0 +1,3 @@ +export function match(param) { + return /^\d+$/.test(param); +} diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page=integer]/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page=integer]/+page.svelte new file mode 100644 index 000000000..df3a52fdf --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page=integer]/+page.svelte @@ -0,0 +1 @@ +

Archive Page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md similarity index 56% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md index 62a02f31c..c69965f7d 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/README.md +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md @@ -4,8 +4,21 @@ title: Layout Groups Sections of your app often share a common UI. To not repeat that code, we can use layouts. These form a hierarchy, a page inherits all layouts above it. Sometimes it's necessary to break out of this hierarchy. For this, we can use layout groups. -In this example we have three pages — the home page, the about page, and a pricing page. The home and pricing page should both have a marketing layout, the about page should not. All three pages are at the same level, so we can't put a common layout for the home and pricing page in the route hierarchy. Instead, we add a group. +In this example we have three pages — the home page, the about page, and a pricing page. The home and pricing page should both have a marketing layout, the about page should not. All three pages are at the same level, so we can't just put a common layout for the home and pricing page in the route hierarchy. To achieve this, we add a group. 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`. -TODO how to do a before/after when we don't have a way to create files? Should we have one? +Create a `(marketing)` folder inside `routes` and move the home and pricing page inside. Last, create a new `+layout.svelte` inside `(marketing)`: + +```diff +src/routes/ ++├ (marketing) +│ ├ about/ +│ │ └ +page.svelte ++│ ├ +layout.svelte ++│ └ +page.svelte +├ pricing/ +│ └ +page.svelte +├ +layout.svelte +-└ +page.svelte +``` diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/+layout.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+layout.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/+layout.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/about/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/pricing/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-a/src/routes/pricing/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/pricing/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/+layout.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+layout.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/+layout.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/(marketing)/pricing/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/+layout.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/+layout.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/+layout.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/about/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-layout-groups/app-b/src/routes/about/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/about/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/README.md new file mode 100644 index 000000000..a4560d58f --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/README.md @@ -0,0 +1,24 @@ +--- +title: Breaking out of layouts +--- + +Layouts form a strict hierarchy. Every page inherits the layout above it, which itself inherits the layout above it and so on. Sometimes it's useful to break out of that hierarchy. + +Let's rewind the layout inside `business/pricing/+page.svelte` to the root `+layout.svelte`. To do that, we add an `@` sign behind `+page.svelte`: + +```diff +src/routes/ +├ business +│ ├ pricing/ +│ │ └ +layout@.svelte ++│ │ └ +page@.svelte +-│ │ └ +page.svelte +│ ├ +layout.svelte +│ └ +page.svelte +├ +layout.svelte +└ +page.svelte +``` + +In general we can reset to one of the upper layouts by appending `@` followed by the segment name. In this example, we could also rewind to `business/+layout.svelte` by writing `+page@business.svelte` + +> The root layout applies to every page of your app, you cannot break out of it. diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..9fdc66cfe --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+layout.svelte @@ -0,0 +1,7 @@ +

Root layout

+ + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..9d2ba64e9 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

Home page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+layout.svelte new file mode 100644 index 000000000..8c6688f2c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+layout.svelte @@ -0,0 +1,2 @@ +

Business layout

+ diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+page.svelte new file mode 100644 index 000000000..c76612803 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/+page.svelte @@ -0,0 +1 @@ +

Business page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+layout.svelte new file mode 100644 index 000000000..ad7bd658e --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+layout.svelte @@ -0,0 +1,2 @@ +

Pricing layout

+ diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+page.svelte new file mode 100644 index 000000000..964ada9fb --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-a/src/routes/business/pricing/+page.svelte @@ -0,0 +1 @@ +

Pricing page

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte new file mode 100644 index 000000000..964ada9fb --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte @@ -0,0 +1 @@ +

Pricing page

From fc83dfd161562a9346141de9023bf2eb5be9c64e Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 25 Nov 2022 16:22:05 +0100 Subject: [PATCH 014/177] use new capabilities to adjust tutorials --- .../01-optional-params/README.md | 13 +++++++++++++ .../{[[optional]] => [lang]}/home/+page.svelte | 0 .../app-b/src/routes/[[lang]]/home/+page.svelte | 8 ++++++++ .../app-b/src/routes/[lang]/__delete | 0 .../app-b/src/routes/archive/[page]/__delete | 0 .../app-b/src/routes/+page.svelte/__delete | 0 .../app-b/src/routes/pricing/__delete | 0 .../routes/business/pricing/+page.svelte/__delete | 0 .../src/{ => routes}/business/pricing/+page@.svelte | 0 9 files changed, 21 insertions(+) rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/{[[optional]] => [lang]}/home/+page.svelte (100%) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[[lang]]/home/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[lang]/__delete create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page]/__delete create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/+page.svelte/__delete create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/pricing/__delete create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/routes/business/pricing/+page.svelte/__delete rename content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/{ => routes}/business/pricing/+page@.svelte (100%) diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md index cadea7828..a9b47ff93 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md @@ -5,3 +5,16 @@ title: Optional Parameters A route like `[lang]/home` contains a parameter named `lang` which is required. Sometimes it's beneficial to make these parameters optional, so that in this example both `home` and `en/home` point to the same page. You can do that by using optional parameters. An optional parameter looks like a required parameter with one more bracket pair around it: `[[optional]]`. The variable name inside - in this case `optional` - is available to the `load` function through the `params` object and also through the `$page.params` store. + +Make the `[lang]` parameter optional by renaming the folder to `[[lang]]`: + +```diff +src/ +├ routes/ +-│ ├ [lang]/ ++│ ├ [[lang]]/ +│ │ ├ [home]/ +│ │ │ └ +page.svelte +│ ├ +layout.svelte +│ └ +page.svelte +``` diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[lang]/home/+page.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[[optional]]/home/+page.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/[lang]/home/+page.svelte diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[[lang]]/home/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[[lang]]/home/+page.svelte new file mode 100644 index 000000000..9250fd499 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[[lang]]/home/+page.svelte @@ -0,0 +1,8 @@ + + +

+ Welcome to the {$page.params.optional ?? + 'default'} home page +

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[lang]/__delete b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-b/src/routes/[lang]/__delete new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page]/__delete b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/app-b/src/routes/archive/[page]/__delete new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/+page.svelte/__delete b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/+page.svelte/__delete new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/pricing/__delete b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-b/src/routes/pricing/__delete new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/routes/business/pricing/+page.svelte/__delete b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/routes/business/pricing/+page.svelte/__delete new file mode 100644 index 000000000..e69de29bb diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/routes/business/pricing/+page@.svelte similarity index 100% rename from content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/business/pricing/+page@.svelte rename to content/tutorial/04-advanced-sveltekit/01-advanced-routing/05-breaking-out-of-layouts/app-b/src/routes/business/pricing/+page@.svelte From d78591643673cee764c0506990b1a6cba6ce472f Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 25 Nov 2022 16:46:13 +0100 Subject: [PATCH 015/177] remove duplicate layout from page --- .../app-a/src/routes/about/+page.svelte | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte index 17363fd17..212bd68ff 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/app-a/src/routes/about/+page.svelte @@ -1,17 +1,3 @@ - -

About

This is the about page.

- - From 33abc42b1ba935dae617227d13bbbc87e6d3e8e5 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 25 Nov 2022 17:20:19 +0100 Subject: [PATCH 016/177] more sections --- .../01-advanced-routing/06-await-parent/README.md | 9 +++++++++ .../06-await-parent/app-a/src/routes/+page.svelte | 1 + .../07-using-both-load-functions/README.md | 14 ++++++++++++++ .../app-a/src/routes/+page.js | 3 +++ .../app-a/src/routes/+page.server.js | 3 +++ .../app-a/src/routes/+page.svelte | 5 +++++ .../app-b/src/routes/+page.js | 3 +++ src/routes/tutorial/[slug]/+page.svelte | 1 + 8 files changed, 39 insertions(+) create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/README.md create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.js create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.server.js create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.svelte create mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-b/src/routes/+page.js diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/README.md new file mode 100644 index 000000000..e754b249a --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/README.md @@ -0,0 +1,9 @@ +--- +title: Using parent data +--- + +Occasionally it's useful for a `load` function to access data from a parent `load` function, which can be done with `await parent()`. + +TODO good example + +> Take care not to introduce waterfalls when using `await parent()`. If you can `fetch` other data that is not dependent on parent data, do that first. diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..c65158e7c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/06-await-parent/app-a/src/routes/+page.svelte @@ -0,0 +1 @@ +

TODO

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/README.md new file mode 100644 index 000000000..73856545e --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/README.md @@ -0,0 +1,14 @@ +--- +title: Using both load functions +--- + +In rare cases, you might need to use both a `+page.server.js` and `+page.js` `load` function together — for example, you might need to return an instance of a custom class that was initialised with data from your server. + +The data returned from the `+page.server.js` `load` function can be accessed through the `data` property passed to the `+page.js` function. Use it to append the strings and return the result: + +```js +// +page.js +export async function load({ +++data+++ }) { + return { greeting: +++data.greeting + +++' and the shared load function' }; +} +``` diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.js new file mode 100644 index 000000000..0dfc8d0b2 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.js @@ -0,0 +1,3 @@ +export async function load({}) { + return { greeting: ' and the shared load function' }; +} diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.server.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.server.js new file mode 100644 index 000000000..8e063ffa2 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.server.js @@ -0,0 +1,3 @@ +export async function load() { + return { greeting: 'Hello from the server load function' }; +} diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.svelte new file mode 100644 index 000000000..7416c4d70 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-a/src/routes/+page.svelte @@ -0,0 +1,5 @@ + + +

{data.greeting}

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-b/src/routes/+page.js b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-b/src/routes/+page.js new file mode 100644 index 000000000..1335829d6 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/07-using-both-load-functions/app-b/src/routes/+page.js @@ -0,0 +1,3 @@ +export async function load({ data }) { + return { greeting: data.greeting + ' and the shared load function' }; +} diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 2fc5855c9..7132a047a 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -57,6 +57,7 @@ b[key] = data.section.b[key]; } } + console.log('b is ', b); } /** @type {import('$lib/types').FileTreeContext} */ From 33f1ea879ff8a269fd794f0129eba8b05885d4ef Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 28 Nov 2022 15:06:17 +0100 Subject: [PATCH 017/177] tweaks --- .../02-routing/07-params/README.md | 30 +++++++++++++++++-- .../07-params/app-a/src/routes/+layout.svelte | 8 +++++ .../07-params/app-a/src/routes/+page.svelte | 2 +- .../07-params/app-b/src/routes/+page.svelte | 1 - .../app-b/src/routes/[page]/+page.js | 3 ++ .../app-b/src/routes/[page]/+page.svelte | 5 ++++ .../02-routing/08-endpoints/README.md | 25 +++++++++++++++- .../app-a/src/routes/+page.svelte | 16 +++++++++- .../app-a/src/routes/api/+server.js | 0 .../app-b/src/routes/api/+server.js | 3 -- .../app-b/src/routes/api/user/+server.js | 5 ++++ .../04-progressive-enhancement/README.md | 2 +- 12 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+layout.svelte delete 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/07-params/app-b/src/routes/[page]/+page.js create mode 100644 content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.svelte delete mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-a/src/routes/api/+server.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js create mode 100644 content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/user/+server.js diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/README.md b/content/tutorial/02-sveltekit/02-routing/07-params/README.md index 97cb71742..88a750d9f 100644 --- a/content/tutorial/02-sveltekit/02-routing/07-params/README.md +++ b/content/tutorial/02-sveltekit/02-routing/07-params/README.md @@ -6,8 +6,34 @@ Many URLs are static, but sometimes it's useful to make them dynamic at certain 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. +Let's create such a route with a parameter. First add `[page]/+page.svelte` and a corresponding `[page]/+page.js`... -TODO example use case +```diff +src/routes/ ++├ [page]/ ++│ ├ +page.js ++│ └ +page.svelte +├ +layout.svelte +└ +page.svelte +``` + +...then access the `page` parameter through the `params` object in the `load` function... + +```js +// [page]/+page.js +export function load({ params }) { + return { page: 'You are on page ' + params.page }; +} +``` + +...and display the data in `[page]/+page.svelte`: + +```html + + +

{data.page}

+``` > 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/+layout.svelte b/content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+layout.svelte new file mode 100644 index 000000000..2345c7cc5 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/07-params/app-a/src/routes/+layout.svelte @@ -0,0 +1,8 @@ + + + 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 index 1333ed77b..e5324dcb6 100644 --- 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 @@ -1 +1 @@ -TODO +

Home Page

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 deleted file mode 100644 index 1333ed77b..000000000 --- a/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/+page.svelte +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.js b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.js new file mode 100644 index 000000000..ec165186b --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.js @@ -0,0 +1,3 @@ +export function load({ params }) { + return { page: 'You are on page ' + params.page }; +} diff --git a/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.svelte b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.svelte new file mode 100644 index 000000000..33233acc5 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/07-params/app-b/src/routes/[page]/+page.svelte @@ -0,0 +1,5 @@ + + +

{data.page}

diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md b/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md index b5f29710c..dbb9c7f0e 100644 --- a/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md +++ b/content/tutorial/02-sveltekit/02-routing/08-endpoints/README.md @@ -6,4 +6,27 @@ So far, we have loaded data directly related to a page. Besides that, SvelteKit 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 +Create a simple endpoint at `api/user/+server.js` with a `GET` method from which you return a JSON response using the standard `Response` object: + +```js +// api/user/+server.js +export function GET() { + return new Response(JSON.stringify({ name: 'John Doe' }), { + headers: { 'content-type': 'application/json' } + }); +} +``` + +Since returning JSON is probably what you want most of the time, SvelteKit provides you with a helper function to save you some boilerplate: + +```js +// api/user/+server.js ++++import { json } from '@sveltejs/kit';+++ + +export function GET() { + ---return new Response(JSON.stringify({ name: 'John Doe' }), { + headers: { 'content-type': 'application/json' } + });--- + +++return json({ name: 'John Doe' });+++ +} +``` 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 index 1333ed77b..407aa188a 100644 --- 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 @@ -1 +1,15 @@ -TODO + + + + +User Info: +
+    {JSON.stringify(user, null, 2)}
+
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 deleted file mode 100644 index e69de29bb..000000000 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 deleted file mode 100644 index 2b90cc4ba..000000000 --- a/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/+server.js +++ /dev/null @@ -1,3 +0,0 @@ -export function GET() { - return new Response(); -} diff --git a/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/user/+server.js b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/user/+server.js new file mode 100644 index 000000000..80671b4c3 --- /dev/null +++ b/content/tutorial/02-sveltekit/02-routing/08-endpoints/app-b/src/routes/api/user/+server.js @@ -0,0 +1,5 @@ +import { json } from '@sveltejs/kit'; + +export function GET() { + return json({ name: 'John Doe' }); +} 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 index 8b9dfe648..4ebd4a428 100644 --- 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 @@ -8,7 +8,7 @@ The easiest way to progressively enhance our `` is to add the `enhance` ac ```svelte From 41c13551a0d07f5df069dfc61c66ea307d06a674 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 28 Nov 2022 15:31:54 +0100 Subject: [PATCH 018/177] remove log --- src/routes/tutorial/[slug]/+page.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 7132a047a..2fc5855c9 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -57,7 +57,6 @@ b[key] = data.section.b[key]; } } - console.log('b is ', b); } /** @type {import('$lib/types').FileTreeContext} */ From b4ed498fff78a70f2ab0246e4788b955a1bac471 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 28 Nov 2022 15:42:45 +0100 Subject: [PATCH 019/177] disable csrf for tutorial --- content/tutorial/common/svelte.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/tutorial/common/svelte.config.js b/content/tutorial/common/svelte.config.js index 821c14379..47c9247d0 100644 --- a/content/tutorial/common/svelte.config.js +++ b/content/tutorial/common/svelte.config.js @@ -1,6 +1,8 @@ /** @type {import('@sveltejs/kit').Config} */ const config = { - kit: {} + kit: { + csrf: false // needed for the form actions tutorial, web container stuff makes this necessary + } }; export default config; From 4e7dbf5915355973d1d42816b8259be268865706 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 11:34:41 +0100 Subject: [PATCH 020/177] more content --- .../01-concepts/01-introducing-sveltekit/README.md | 2 -- .../01-concepts/03-server-and-client/README.md | 6 +++++- .../01-concepts/04-server-side-rendering/README.md | 4 +++- .../02-sveltekit/01-concepts/05-prerendering/README.md | 8 +++++++- .../01-rendering-options-basics/README.md | 4 ++-- .../02-sveltekit/06-rendering-options/02-ssr/README.md | 10 ++++++++-- .../02-ssr/app-a/src/routes/+page.svelte | 3 ++- .../02-ssr/app-b/src/routes/+page.js | 1 + .../06-rendering-options/04-prerender/README.md | 2 +- 9 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-b/src/routes/+page.js diff --git a/content/tutorial/02-sveltekit/01-concepts/01-introducing-sveltekit/README.md b/content/tutorial/02-sveltekit/01-concepts/01-introducing-sveltekit/README.md index 500297f91..017943226 100644 --- a/content/tutorial/02-sveltekit/01-concepts/01-introducing-sveltekit/README.md +++ b/content/tutorial/02-sveltekit/01-concepts/01-introducing-sveltekit/README.md @@ -2,8 +2,6 @@ title: What is SvelteKit? --- -> WARNING: this content is a work in progress and is not up to date with breaking changes in the latest version of SvelteKit. For the latest information, refer to the [SvelteKit docs](https://kit.svelte.dev/docs). - So far, we've been working on individual components, or groups of components, in isolation. But to build a complete app, you need more than just components. That's where SvelteKit comes in. Whereas Svelte is a _component framework_, SvelteKit is an _app framework_ (or 'metaframework', depending on who you ask) that solves the tricky problems of building something production-ready: 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 feb6bb0c7..94eb10946 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,4 +8,8 @@ A SvelteKit app can be thought of as two distinct entities working in tandem — 'Client' refers to the JavaScript that loads in the browser. -TODO +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. + +> You can adjust this behavior to your liking if you want - SvelteKit is very versatile! 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 e5046f007..541d0bfbc 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,4 +2,6 @@ title: Server-side rendering --- -TODO +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. + +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)). 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 8e98db599..f2a49296a 100644 --- a/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md +++ b/content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md @@ -2,4 +2,10 @@ title: Prerendering --- -TODO +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. + +This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process is more expensive and prerendered content can only be updated by building and deploying a new version of the application. + +Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain actions. 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. diff --git a/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md index 4442d70c2..b27266b25 100644 --- a/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md +++ b/content/tutorial/02-sveltekit/06-rendering-options/01-rendering-options-basics/README.md @@ -2,11 +2,11 @@ title: Rendering Options Basics --- -SvelteKit let's you customize when and how pages are rendered. +SvelteKit lets you customize when and how pages are rendered. By default, SvelteKit will render (or prerender) any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called hydration. For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a router that takes over subsequent navigations. -You can control each of these on a page-by-page basis by exporting options from `+page.js` or `+page.server.js`, or for groups of pages using a shared `+layout.js` or `+layout`. To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered. +You can control each of these on a page-by-page basis by exporting options from `+page.js` or `+page.server.js`, or for groups of pages using a shared `+layout.js` or `+layout.server.js`. To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered. You can mix and match these options in different areas of your app. For example you could prerender your marketing page for maximum speed, server-render your dynamic pages for SEO and accessibility and turn your admin section into an SPA by rendering it on the client only. This makes SvelteKit very versatile. diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md index 7e817f634..e7eb01476 100644 --- a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md @@ -4,6 +4,12 @@ title: Server Side Rendering The `ssr` option controls whether or not a page is rendered on the server. -By default this option is set to `true`. Setting this option to `false` will make the page render on the client only - if you enable it for your whole app, you've turned it into an SPA. +By default this option is set to `true`. Setting this option to `false` will make the page render on the client only. -Setting it to `false` is useful if you have things on your page that should not or even cannot run on the server. TODO good example +Setting it to `false` is useful if you have things on your page that should not or even cannot run on the server. Let's add this option to ours inside `+page.js`: + +```js ++++export const ssr = false;+++ +``` + +> If you set `ssr` to `false` inside your root `+layout.js`, you turn your SvelteKit app into an SPA! diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte index e6e9ef8cd..254b88bf1 100644 --- a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte @@ -1,3 +1,4 @@ diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-b/src/routes/+page.js b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-b/src/routes/+page.js new file mode 100644 index 000000000..a3d15781a --- /dev/null +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-b/src/routes/+page.js @@ -0,0 +1 @@ +export const ssr = false; diff --git a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md index 7ef474026..58dda685f 100644 --- a/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md +++ b/content/tutorial/02-sveltekit/06-rendering-options/04-prerender/README.md @@ -12,6 +12,6 @@ Setting it to `true` is useful if you have pages that don't have any dependency +++export const prerender = true;+++ ``` -To really see this in effect, you'd need to run the build step, which we can't in this tutorial. +To really see this in effect, you'd need to run the build step and look at the result in preview mode, which we can't in this tutorial. > If you set `prerender` to `true` inside your root `+layout.js`, you turn SvelteKit into a static site generator! From 237c9a0944d1476fd537e6620605f5371706fdae Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 11:42:49 +0100 Subject: [PATCH 021/177] fix interval --- .../02-sveltekit/05-invalidation/01-refresh-data/README.md | 5 ++++- .../01-refresh-data/app-b/src/routes/+page.svelte | 5 +++-- .../05-invalidation/02-custom-data-dependencies/README.md | 5 +++-- .../app-a/src/routes/+page.svelte | 5 +++-- .../app-b/src/routes/+page.svelte | 5 +++-- .../05-invalidation/03-refresh-all-data/README.md | 5 +++-- .../03-refresh-all-data/app-a/src/routes/+page.svelte | 5 +++-- .../03-refresh-all-data/app-b/src/routes/+page.svelte | 5 +++-- 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md index 4867624e5..d3cc99545 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/README.md @@ -25,7 +25,10 @@ export async function load({ fetch }) { export let data; +++onMount(() => { - const interval = setInterval(() => invalidate('/api/clock')); + const interval = setInterval( + () => invalidate('/api/clock'), + 1000 + ); return () => clearInterval(interval); });+++ diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte index 334668ffd..0aa1ae894 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-b/src/routes/+page.svelte @@ -5,8 +5,9 @@ export let data; onMount(() => { - const interval = setInterval(() => - invalidate('/api/clock') + const interval = setInterval( + () => invalidate('/api/clock'), + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md index f871b18e1..d89398275 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/README.md @@ -25,8 +25,9 @@ export async function load({ ---fetch---+++depends+++ }) { export let data; onMount(() => { - const interval = setInterval(() => - invalidate(---'/api/clock'---+++'tick:tock'+++) + const interval = setInterval( + () => invalidate(---'/api/clock'---+++'tick:tock'+++), + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte index 334668ffd..0aa1ae894 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-a/src/routes/+page.svelte @@ -5,8 +5,9 @@ export let data; onMount(() => { - const interval = setInterval(() => - invalidate('/api/clock') + const interval = setInterval( + () => invalidate('/api/clock'), + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte index a1a2ef68e..363b5abf7 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/02-custom-data-dependencies/app-b/src/routes/+page.svelte @@ -5,8 +5,9 @@ export let data; onMount(() => { - const interval = setInterval(() => - invalidate('tick:tock') + const interval = setInterval( + () => invalidate('tick:tock'), + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md index e89066f81..97c617ee5 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/README.md @@ -14,8 +14,9 @@ Let's use `invalidateAll` in our clock example. First we'll update the component export let data; onMount(() => { - const interval = setInterval(() => - ---invalidate('tick:tock')---+++invalidateAll()+++ + const interval = setInterval( + () => ---invalidate('tick:tock')---+++invalidateAll()+++, + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte index a1a2ef68e..363b5abf7 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-a/src/routes/+page.svelte @@ -5,8 +5,9 @@ export let data; onMount(() => { - const interval = setInterval(() => - invalidate('tick:tock') + const interval = setInterval( + () => invalidate('tick:tock'), + 1000 ); return () => clearInterval(interval); }); diff --git a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte index c55b64da7..0e2143cb8 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/03-refresh-all-data/app-b/src/routes/+page.svelte @@ -5,8 +5,9 @@ export let data; onMount(() => { - const interval = setInterval(() => - invalidateAll() + const interval = setInterval( + () => invalidateAll(), + 1000 ); return () => clearInterval(interval); }); From d2f129a5d1189253342b844acd269c95e10df5a3 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 11:48:17 +0100 Subject: [PATCH 022/177] leverage adding files functionality for error tutorial --- .../01-error-pages/README.md | 16 +++++++++++++++- .../src/routes/about/+error.svelte | 0 2 files changed, 15 insertions(+), 1 deletion(-) rename content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/{app-a => app-b}/src/routes/about/+error.svelte (100%) diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md index 300ef0e39..a4da44b69 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md @@ -4,6 +4,20 @@ title: Error Pages If something goes wrong during executing the `load` functions for a page, we can "catch" these errors with `+error.svelte` pages. -For teaching purposes, we created a `+page.js` `load` function which throws an error. That error will bubble up the file tree until it finds a `+error.svelte` or falls back to a generic error page if there's none. In this example we placed one right next to the erroring `+page.js` - notice how the outer layout still renders and keeps the app functioning. +To showcase this, our `+page.js` `load` function throws an error. That error will bubble up the file tree until it finds a `+error.svelte` or falls back to a generic error page if there's none - which is what happens right now. + +Let's place a `+error.svelte` file right next to the erroring `+page.js`: + +```diff +src/routes/ +├ about/ ++│ ├ +error.svelte +│ ├ +page.js +│ └ +page.svelte +├ +layout.svelte +└ +page.svelte +``` + +Notice how now the outer layout still renders after the error and keeps the app functioning. Inside `+error.svelte`, you are free to put any content you like. Just play around with it a little! diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-b/src/routes/about/+error.svelte similarity index 100% rename from content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-a/src/routes/about/+error.svelte rename to content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/app-b/src/routes/about/+error.svelte From 1ab3d65e91b9aa0b48a5d0bc53ed4d5822060767 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 11:55:22 +0100 Subject: [PATCH 023/177] simplify --- .../02-custom-error-messages/README.md | 14 ++------------ .../03-expected-errors/README.md | 2 -- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md index 970ab5584..523d09532 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md @@ -17,7 +17,7 @@ For this, SvelteKit provides you with `$page.error` and `$page.status`, which co That's better, but `$page.error.message` always contains "Internal Error" - how so? This is because SvelteKit plays it safe and prevents you from accidentally showing sensitive information as part of the error message. -To customize it, we implement the `handleError` hook in `hooks.server.js` and `hooks.client.js` which run when an unexpected error is thrown during data loads on the server or client respectively. +To customize it, implement the `handleError` hook in `hooks.server.js` and `hooks.client.js` which run when an unexpected error is thrown during data loads on the server or client respectively. ```js // hooks.server.js @@ -37,16 +37,6 @@ export function handleError(+++{ error }+++) { You could also call your error reporting service in these hooks. -Note that you can return more than an error message if you like. Whatever object shape you return will be available in `$page.error`, the only requirement is a `message` property. You can even make it type-safe by typing the error object inside `app.d.ts` be defining an `Error` interface with the right shape: - -```js -// app.d.ts -declare namespace App { - interface Error { - message: string; - somethingElse: number; - } -} -``` +Note that you can return more than an error message if you like. Whatever object shape you return will be available in `$page.error`, the only requirement is a `message` property. You can read more about this (and how to make it type-safe!) in the [error docs](https://kit.svelte.dev/docs/errors). > When handling errors, be careful to not assume it's an `Error` object, anything could be thrown. Also make sure not to expose senstive data by forwarding too much information diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md index 3ca607098..301dc792a 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md @@ -16,5 +16,3 @@ export function load() { ``` In contrast to unexpected error, the message of `error`s you throw yourself this way do _not_ call the `handleError` hook and are propagated to `$page.error` directly. - -> If you defined the error shape through the `App.Error` interface, the second parameter passed to the `error` function expects this shape. From ae0c8a5a244d72bdf9aeb5f809fde86190486603 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 15:25:52 +0100 Subject: [PATCH 024/177] tweak tutorials so people have to create the files --- .../02-routing/01-pages/README.md | 21 +++++++++--- .../app-a/src/routes/about/+page.svelte | 4 --- .../02-routing/02-layouts/README.md | 16 +++++++-- .../app-a/src/routes/+layout.svelte | 1 - .../02-routing/03-loading-data/README.md | 24 +++++++++----- .../03-loading-data/app-a/src/routes/+page.js | 0 .../04-loading-layout-data/README.md | 27 ++++++++++----- .../app-a/src/routes/+layout.js | 0 .../app-a/src/routes/+page.js | 4 --- .../app-a/src/routes/+page.svelte | 6 +--- .../app-a/src/routes/about/+page.svelte | 1 - .../05-loading-server-data/README.md | 24 +++++++++----- .../app-a/src/routes/+page.server.js | 1 - .../06-loading-layout-server-data/README.md | 33 +++++++++++-------- .../app-a/src/routes/+layout.server.js | 1 - .../app-a/src/routes/+layout.svelte | 5 --- .../app-a/src/routes/+page.server.js | 6 ---- .../app-a/src/routes/+page.svelte | 6 +--- .../app-a/src/routes/about/+page.svelte | 1 - .../app-b/src/routes/+layout.svelte | 7 ---- 20 files changed, 101 insertions(+), 87 deletions(-) delete mode 100644 content/tutorial/02-sveltekit/02-routing/01-pages/app-a/src/routes/about/+page.svelte delete mode 100644 content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+layout.svelte delete mode 100644 content/tutorial/02-sveltekit/02-routing/03-loading-data/app-a/src/routes/+page.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+layout.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/+page.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/app-a/src/routes/about/+page.svelte delete mode 100644 content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-a/src/routes/+page.server.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+layout.server.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/+page.server.js delete mode 100644 content/tutorial/02-sveltekit/02-routing/06-loading-layout-server-data/app-a/src/routes/about/+page.svelte 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 b67fcdfe3..a429b8a81 100644 --- a/content/tutorial/02-sveltekit/02-routing/01-pages/README.md +++ b/content/tutorial/02-sveltekit/02-routing/01-pages/README.md @@ -6,13 +6,24 @@ SvelteKit uses filesystem-based routing, which means that the _routes_ of your a 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. +In this app we currently have one route — `src/routes/+page.svelte`, which maps to `/`. -> 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. +Let's add a second route, `src/routes/about/+page.svelte`, which maps to `/about`: -Let's add a link in `src/routes/about/+page.svelte` back to the homepage: +```diff +src/routes/ ++├ about/ ++│ └ +page.svelte +└ +page.svelte +``` + +Clicking the `about` link on the home page will now take you to the about page (which is empty right now). + +Let's add some content (including a link back to the homepage) to `src/routes/about/+page.svelte` : ```svelte -

This is the about page.

-

Go to the ++++++home++++++ page

++++

This is the about page.

+

Go to the home page

+++ ``` + +> Unlike traditional multi-page apps, navigating to `/about` and back 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/01-pages/app-a/src/routes/about/+page.svelte b/content/tutorial/02-sveltekit/02-routing/01-pages/app-a/src/routes/about/+page.svelte deleted file mode 100644 index b74a0b67c..000000000 --- a/content/tutorial/02-sveltekit/02-routing/01-pages/app-a/src/routes/about/+page.svelte +++ /dev/null @@ -1,4 +0,0 @@ -

About

- -

This is the about page.

-

Go to the home page

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 eaad27dfb..263914837 100644 --- a/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md +++ b/content/tutorial/02-sveltekit/02-routing/02-layouts/README.md @@ -8,16 +8,26 @@ In this app we have two routes — `src/routes/+page.svelte`, and `src/routes/ab 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`: +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: + +```diff +src/routes/ +├ about/ +│ └ +page.svelte ++├ +layout.svelte +└ +page.svelte +``` + +Then remove the duplicated content from the `+page.svelte` files and add it to `+layout.svelte` instead: ```svelte +++ -+++ + -+++ + -+++ ++++ ``` > Layouts can also be nested 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 index 78d89ac7f..668256347 100644 --- 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 @@ -21,7 +21,7 @@ Then add the `load` function, calling the API inside, and passing the result to ```js +++export async function load({ fetch }) { - const greeting = await fetch('/api?layout').then((r) => r.text()); + const greeting = await fetch('/api').then((r) => r.text()); return { greeting }; }+++ ``` 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..b351deb56 --- /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 index 8ae732d1f..79b389602 100644 --- 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 @@ -1,5 +1,5 @@ // We'll get to +server.js in a later chapter -export function GET({ url }) { - return new Response('Hello ' + url.search); +export function GET() { + return new Response('Hello from your API'); } 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 index 8b1baa17a..560f092f9 100644 --- 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 @@ -1,4 +1,4 @@ export async function load({ fetch }) { - const greeting = await fetch('/api?layout').then((r) => r.text()); + const greeting = await fetch('/api').then((r) => r.text()); return { 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 index ec89d80c7..bc1d60531 100644 --- 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 @@ -20,7 +20,7 @@ Then make a call to our fake database inside `src/routes/+page.server.js` and sh import { db } from './fake-db.js'; +++export async function load() { - const greeting = await db.getGreeting(); + const greeting = await db.greet(); return { greeting }; }+++ ``` 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 index 19e094e31..bbb1589b1 100644 --- 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 @@ -1,3 +1,3 @@ export const db = { - getGreeting: () => Promise.resolve('Hello from your fake data base') + greet: () => 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 index 8e2b361b4..9638b7cd4 100644 --- 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 @@ -1,6 +1,6 @@ import { db } from './fake-db'; export async function load() { - const greeting = await db.getGreeting(); + const greeting = await db.greet(); return { 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 deleted file mode 100644 index 19e094e31..000000000 --- a/content/tutorial/02-sveltekit/02-routing/05-loading-server-data/app-b/src/routes/fake-db.js +++ /dev/null @@ -1,3 +0,0 @@ -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 index c2c981d07..6a2758331 100644 --- 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 @@ -24,7 +24,7 @@ Then make a call to our fake database inside `src/routes/+layout.server.js` and +++import { db } from './fake-db.js'; export async function load() { - const greeting = await db.getGreeting('layout'); + const greeting = await db.greet(); return { greeting }; }+++ ``` 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 6c891a649..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 @@ -1,3 +1,8 @@

TODO

+ + 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..b351deb56 --- /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 index fa47d6688..bbb1589b1 100644 --- 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 @@ -1,3 +1,3 @@ export const db = { - getGreeting: (toGreet) => Promise.resolve('Hello ' + toGreet) + greet: () => Promise.resolve('Hello from your fake data base') }; 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 index dc4a1fefa..9638b7cd4 100644 --- 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 @@ -1,6 +1,6 @@ import { db } from './fake-db'; export async function load() { - const greeting = await db.getGreeting('layout'); + const greeting = await db.greet(); 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 index a791437ec..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 @@ -3,3 +3,10 @@

{data.greeting}

+ + + + From 889bee144e4165bae9e5e1dd312050068abc2e7c Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 1 Dec 2022 18:13:26 +0100 Subject: [PATCH 026/177] tweaks and fixes --- .../02-sveltekit/03-mutating-data/01-forms/README.md | 4 +++- .../03-mutating-data/02-form-validation/README.md | 2 +- .../02-form-validation/app-b/src/routes/+page.server.js | 2 +- .../03-mutating-data/03-named-form-actions/README.md | 8 ++++---- .../app-a/src/routes/+page.server.js | 2 +- .../app-b/src/routes/+page.server.js | 4 ++-- .../app-a/src/routes/+page.server.js | 4 ++-- .../03-mutating-data/05-customizing-use-enhance/README.md | 2 +- .../app-a/src/routes/+page.server.js | 4 ++-- 9 files changed, 17 insertions(+), 15 deletions(-) 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 index 3c3b22758..dcbd039cc 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md +++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md @@ -4,9 +4,11 @@ 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 `` elements. -Let's create a login form with email and password. First we write the HTML: +Let's create a login form with email and password. First we write the HTML in `+page.svelte`: ```svelte +

Please log in

+ +++ 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 index c1205316b..f8bcf5303 100644 --- 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 @@ -10,7 +10,7 @@ In `+page.server.js` we do that by first getting the form data from the `request import { redirect, +++invalid+++ } from '@sveltejs/kit'; export const actions = { - default: +++async+++ (+++request+++) => { + 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' }); diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js index dbbfa49a4..07213d915 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js +++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js @@ -1,7 +1,7 @@ import { redirect } from '@sveltejs/kit'; export const actions = { - default: async (request) => { + 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' }); 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 index 1ae40d73f..7af58f581 100644 --- 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 @@ -11,7 +11,7 @@ Let's add a "Register" button to our existing form and introduce two form action export let form; - + {#if form?.message} @@ -32,14 +32,14 @@ In `+page.server.js`, we react to these named actions by adding them as properti import { redirect, invalid } from '@sveltejs/kit'; export const actions = { - ---default---+++login+++: async (request) => { + ---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) => { + }+++, + register: async ({ request }) => { const fields = await request.formData(); if (fields.get('email') === 'svelte@kit.dev') { return invalid(422, { message: 'Email already in use' }); 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 index dbbfa49a4..07213d915 100644 --- 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 @@ -1,7 +1,7 @@ import { redirect } from '@sveltejs/kit'; export const actions = { - default: async (request) => { + 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' }); diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js index 369fcce46..1659c832b 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js +++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.server.js @@ -1,14 +1,14 @@ import { redirect, invalid } from '@sveltejs/kit'; export const actions = { - login: async (request) => { + 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) => { + register: async ({ request }) => { const fields = await request.formData(); if (fields.get('email') === 'svelte@kit.dev') { return invalid(422, { message: 'Email already in use' }); diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js index 369fcce46..1659c832b 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.server.js @@ -1,14 +1,14 @@ import { redirect, invalid } from '@sveltejs/kit'; export const actions = { - login: async (request) => { + 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) => { + register: async ({ request }) => { const fields = await request.formData(); if (fields.get('email') === 'svelte@kit.dev') { return invalid(422, { message: 'Email already in use' }); 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 index 4ff45b952..9e43efa44 100644 --- 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 @@ -8,7 +8,7 @@ In the last chapter we have seen how to progressively enhance our `` by ad { 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 index 369fcce46..1659c832b 100644 --- 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 @@ -1,14 +1,14 @@ import { redirect, invalid } from '@sveltejs/kit'; export const actions = { - login: async (request) => { + 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) => { + register: async ({ request }) => { const fields = await request.formData(); if (fields.get('email') === 'svelte@kit.dev') { return invalid(422, { message: 'Email already in use' }); From 9d943c59411a2b41c08064430d69628e7e9de000 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 2 Dec 2022 10:34:39 +0100 Subject: [PATCH 027/177] Update content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md Co-authored-by: Geoff Rich <4992896+geoffrich@users.noreply.github.com> --- .../03-mutating-data/04-progressive-enhancement/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 4ebd4a428..f51957e0e 100644 --- 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 @@ -25,7 +25,7 @@ The easiest way to progressively enhance our `` is to add the `enhance` ac 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 , form and $page will not be updated. This is because in the native form submission case you would be redirected to the page the action is on. +- 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 ``, `form` and `$page` will not be updated. This is because in the native form submission case you would be redirected to the page the action is on. - invalidate all data on a successful response - navigate to the new page on a redirect response - render the nearest error page if an error occurs From 1f371e941057af7fb61f2e952e26404d81221bc7 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 2 Dec 2022 10:53:03 +0100 Subject: [PATCH 028/177] switch example, because alert will prevent the ping events, resulting in an endless alert loop because of constant iframe reloads --- .../02-ssr/app-a/src/routes/+page.svelte | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte index 254b88bf1..0f9640e09 100644 --- a/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/06-rendering-options/02-ssr/app-a/src/routes/+page.svelte @@ -1,4 +1,8 @@ + +

+ The initially focused element is: {focused} +

From 3b1226d2e14a365031519b34818c407e8ce517fb Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 2 Dec 2022 10:56:01 +0100 Subject: [PATCH 029/177] labels for inputs --- .../02-sveltekit/03-mutating-data/01-forms/README.md | 10 ++++++++-- .../01-forms/app-b/src/routes/+page.svelte | 10 ++++++++-- .../03-mutating-data/02-form-validation/README.md | 10 ++++++++-- .../02-form-validation/app-a/src/routes/+page.svelte | 10 ++++++++-- .../02-form-validation/app-b/src/routes/+page.svelte | 10 ++++++++-- .../03-mutating-data/03-named-form-actions/README.md | 10 ++++++++-- .../app-a/src/routes/+page.svelte | 10 ++++++++-- .../app-b/src/routes/+page.svelte | 10 ++++++++-- .../04-progressive-enhancement/README.md | 10 ++++++++-- .../app-a/src/routes/+page.svelte | 10 ++++++++-- .../app-b/src/routes/+page.svelte | 10 ++++++++-- .../05-customizing-use-enhance/README.md | 10 ++++++++-- .../app-a/src/routes/+page.svelte | 10 ++++++++-- .../app-b/src/routes/+page.svelte | 10 ++++++++-- 14 files changed, 112 insertions(+), 28 deletions(-) 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 index dcbd039cc..56d7994a8 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md +++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/README.md @@ -10,8 +10,14 @@ Let's create a login form with email and password. First we write the HTML in `+

Please log in

+++ - - + + +++ ``` diff --git a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte index 62424d768..73c86ab7f 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/01-forms/app-b/src/routes/+page.svelte @@ -1,7 +1,13 @@

Please log in

- - + +
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 index f8bcf5303..b0f237b2e 100644 --- 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 @@ -30,8 +30,14 @@ What's left to do is displaying that error message. Whatever is returned from `i

Please log in

- - + + +++{#if form?.message} {form?.message} {/if}+++ 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 index 62424d768..73c86ab7f 100644 --- 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 @@ -1,7 +1,13 @@

Please log in

- - + +
diff --git a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte index 1663d3525..dc8b3a7df 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.svelte @@ -5,8 +5,14 @@

Please log in

- - + + {#if form?.message} {form?.message} {/if} 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 index 7af58f581..d15401d94 100644 --- 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 @@ -12,8 +12,14 @@ Let's add a "Register" button to our existing form and introduce two form action - - + + {#if form?.message} {form?.message} {/if} 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 index e7e1316bc..08900254b 100644 --- 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 @@ -3,8 +3,14 @@ - - + + {#if form?.message} {form?.message} {/if} diff --git a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte index 9d9760c5e..6dcc94097 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/03-named-form-actions/app-b/src/routes/+page.svelte @@ -5,8 +5,14 @@

Please log in

- - + + {#if form?.message} {form?.message} {/if} 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 index 4ebd4a428..81c82e217 100644 --- 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 @@ -13,8 +13,14 @@ The easiest way to progressively enhance our `` is to add the `enhance` ac - - + + {#if form?.message} {form?.message} {/if} diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte index 9d9760c5e..6dcc94097 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-a/src/routes/+page.svelte @@ -5,8 +5,14 @@

Please log in

- - + + {#if form?.message} {form?.message} {/if} diff --git a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte index 0d38015c1..e642cb832 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/app-b/src/routes/+page.svelte @@ -6,8 +6,14 @@

Please log in

- - + + {#if form?.message} {form?.message} {/if} 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 index 9e43efa44..554f92d29 100644 --- 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 @@ -18,8 +18,14 @@ In the last chapter we have seen how to progressively enhance our `` by ad submitting = false; } }}+++> - - + + {#if form?.message} {form?.message} {/if} 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 index 0d38015c1..e642cb832 100644 --- 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 @@ -6,8 +6,14 @@

Please log in

- - + + {#if form?.message} {form?.message} {/if} diff --git a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte index fd9fb644b..8927c2f41 100644 --- a/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/03-mutating-data/05-customizing-use-enhance/app-b/src/routes/+page.svelte @@ -17,8 +17,14 @@ }; }} > - - + + {#if form?.message} {form?.message} {/if} From 2d97045931c9d773cefeabed6f6afaa776cc0446 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 2 Dec 2022 12:48:00 +0100 Subject: [PATCH 030/177] tweaks and fixes --- .../01-error-pages/README.md | 2 +- .../02-custom-error-messages/README.md | 2 +- .../03-expected-errors/README.md | 2 +- .../04-redirects/README.md | 2 +- .../app-a/src/routes/+page.svelte | 2 ++ .../01-optional-params/README.md | 4 +++- .../app-a/src/routes/+layout.svelte | 6 ++++-- .../02-rest-params/README.md | 17 ++++++++++++++--- .../app-a/src/routes/+error.svelte | 8 ++++++-- .../app-a/src/routes/+layout.svelte | 2 ++ .../app-a/src/routes/[...rest]/+page.js | 0 .../app-b/src/routes/[...rest]/+page.js | 4 ++-- .../03-param-matchers/README.md | 6 +++--- 13 files changed, 40 insertions(+), 17 deletions(-) delete mode 100644 content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/[...rest]/+page.js diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md index a4da44b69..fd5faaf46 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/01-error-pages/README.md @@ -4,7 +4,7 @@ title: Error Pages If something goes wrong during executing the `load` functions for a page, we can "catch" these errors with `+error.svelte` pages. -To showcase this, our `+page.js` `load` function throws an error. That error will bubble up the file tree until it finds a `+error.svelte` or falls back to a generic error page if there's none - which is what happens right now. +To showcase this, the `src/routes/about/+page.js` `load` function throws an error. That error will bubble up the file tree until it finds a `+error.svelte` or falls back to a generic error page if there's none - which is what happens right now. Navigate to the about page to see it in action Let's place a `+error.svelte` file right next to the erroring `+page.js`: diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md index 523d09532..378e8e39b 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/02-custom-error-messages/README.md @@ -12,7 +12,7 @@ For this, SvelteKit provides you with `$page.error` and `$page.status`, which co +++

{$page.status}

On no, something went wrong!

-+++

{$page.error.message}

++++

{$page.error.message}

+++ ``` That's better, but `$page.error.message` always contains "Internal Error" - how so? This is because SvelteKit plays it safe and prevents you from accidentally showing sensitive information as part of the error message. diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md index 301dc792a..75c3789cb 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/03-expected-errors/README.md @@ -15,4 +15,4 @@ export function load() { } ``` -In contrast to unexpected error, the message of `error`s you throw yourself this way do _not_ call the `handleError` hook and are propagated to `$page.error` directly. +In contrast to unexpected errors, the message of `error`s you throw yourself do _not_ call the `handleError` hook and are propagated to `$page.error` directly. diff --git a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md index 0acf06666..8f988020d 100644 --- a/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md +++ b/content/tutorial/02-sveltekit/04-errors-and-redirects/04-redirects/README.md @@ -4,7 +4,7 @@ title: Redirects Besides errors there's one more thing you can `throw`, and that's `redirect`s. -Let's use that navigate away from our login page when we're logged in. +Let's use that to navigate away from our login page when we're logged in. ```js // login/+page.js diff --git a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte index e6e9ef8cd..69030c7dd 100644 --- a/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte +++ b/content/tutorial/02-sveltekit/05-invalidation/01-refresh-data/app-a/src/routes/+page.svelte @@ -1,3 +1,5 @@ + +
{data.time}
diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md index a9b47ff93..9c23f32cf 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md @@ -2,7 +2,9 @@ title: Optional Parameters --- -A route like `[lang]/home` contains a parameter named `lang` which is required. Sometimes it's beneficial to make these parameters optional, so that in this example both `home` and `en/home` point to the same page. You can do that by using optional parameters. +Congratulations, you've gone through the whole advanced Svelte tutorial! Now let's get to the final chapter - the advanced SvelteKit tutorial. We'll start with optional route parameters. + +A route like `[lang]/home` contains a parameter named `lang` which is required. Sometimes it's beneficial to make these parameters optional, so that in this example both `home` and `en/home` point to the same page (right now the former results in a 404 page). You can do that by using optional parameters. An optional parameter looks like a required parameter with one more bracket pair around it: `[[optional]]`. The variable name inside - in this case `optional` - is available to the `load` function through the `params` object and also through the `$page.params` store. diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte index 45ec290f2..7d55c56fa 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/app-a/src/routes/+layout.svelte @@ -1,6 +1,8 @@

- Go to the default home page. + Go to the default home page.

- Go to the english home page. + Go to the english home page.

+ + diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md index e8e2281ed..eae259dd7 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md @@ -6,13 +6,24 @@ The number of route segments might be unknown sometimes. Other times, you might Rest parameters look like an array spread: `[...rest]`. The variable name inside - in this case `rest` - is available to the `load` function through the `params` object and also through the `$page.params` store. -Let's use this rest parameter to implement a catch-all route to redirect to our nice-look error page instead. Add the following to `[...rest]/+page.js`: +Let's use this rest parameter to implement a catch-all route to redirect to our better-looking error page instead. First add `[...rest]/+page.js` to `src/routes`: + +```diff +src/routes/ ++├ [...rest]/ ++│ └ +page.svelte +├ +error.svelte +├ +layout.svelte +└ +page.svelte +``` + +Then add a `load` function to it which throws a 404: ```js +++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/02-rest-params/app-a/src/routes/+error.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte index 803d46d09..b0886cf30 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+error.svelte @@ -1,3 +1,7 @@ -

404

+ -

Page not found

+

{$page.status}

+ +

{$page.error.message}

diff --git a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte index 84d573522..f0dfff39a 100644 --- a/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte +++ b/content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/app-a/src/routes/+layout.svelte @@ -5,3 +5,5 @@ Go to a non-existing page.

+ + 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} +

diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-b/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..bf5c9d2a7 --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/01-private-static/app-b/src/routes/+page.svelte @@ -0,0 +1,7 @@ + + +

+ 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: {SECRET} +

diff --git a/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-b/src/routes/+page.svelte b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-b/src/routes/+page.svelte new file mode 100644 index 000000000..3679ac42c --- /dev/null +++ b/content/tutorial/04-advanced-sveltekit/02-environment-variables/03-private-dynamic/app-b/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}

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 index 3e58c4f05..234bef82f 100644 --- 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 @@ -1,8 +1,8 @@

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 +++