Skip to content

Commit 2ab9dba

Browse files
dummdidummtanhauhaugeoffrichRich-Harrisbenmccann
authored
tutorial (sveltejs#105)
* start of routing tutorial * more chapters * slots * chapter skeletons * mutating data section * Apply suggestions from code review Co-authored-by: Tan Li Hau <tanhauhau@users.noreply.github.com> * errors and redirects chapter * invalidation chapter * render options section * add missing meta.json files * advanced routing wip * fix link * matching, groups * use new capabilities to adjust tutorials * remove duplicate layout from page * more sections * tweaks * remove log * disable csrf for tutorial * more content * fix interval * leverage adding files functionality for error tutorial * simplify * tweak tutorials so people have to create the files * tweaks * tweaks and fixes * Update content/tutorial/02-sveltekit/03-mutating-data/04-progressive-enhancement/README.md Co-authored-by: Geoff Rich <4992896+geoffrich@users.noreply.github.com> * switch example, because alert will prevent the ping events, resulting in an endless alert loop because of constant iframe reloads * labels for inputs * tweaks and fixes * fix * environment variables tutorial * fixes * Update content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/+page.svelte Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/app-a/src/routes/about/+page.svelte Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/02-layouts/app-b/src/routes/+layout.svelte Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/04-loading-layout-data/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/02-routing/07-params/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/03-mutating-data/02-form-validation/app-b/src/routes/+page.server.js Co-authored-by: Rich Harris <hello@rich-harris.dev> * lowercase Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/06-rendering-options/02-ssr/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/02-sveltekit/06-rendering-options/03-csr/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/04-advanced-sveltekit/01-advanced-routing/01-optional-params/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/04-advanced-sveltekit/01-advanced-routing/02-rest-params/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/04-advanced-sveltekit/01-advanced-routing/03-param-matchers/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * Update content/tutorial/04-advanced-sveltekit/01-advanced-routing/04-layout-groups/README.md Co-authored-by: Rich Harris <hello@rich-harris.dev> * move explanatory content from concepts into render options chapter * remove backticks * Update content/tutorial/02-sveltekit/02-routing/05-loading-server-data/README.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> * Update content/tutorial/02-sveltekit/02-routing/03-loading-data/README.md * Loading (sveltejs#115) * shuffle sections around * update error page * update params section * rename * update some content * HN example * update API route docs * fix script * tweaks * typo * fixes * fix * tweaks * use __delete * add some css * allow files to be marked for deletion * [chore] bump deps * [chore] robustify create-middleware Co-authored-by: Rich Harris <hello@rich-harris.dev> * [chore] handle offline case in +error.svelte Co-authored-by: Rich Harris <hello@rich-harris.dev> * [fix] style "/// file: .." pragmas in code blocks Co-authored-by: Rich Harris <hello@rich-harris.dev> * [feat] __delete inside file means delete that file Co-authored-by: Rich Harris <hello@rich-harris.dev> * next * fix lockfile * tweaks * [feat] __hidden file to mark folders as hidden * use hidden API instead * Update content/tutorial/02-sveltekit/02-routing/07-api-routes/README.md Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com> Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> * fix casing * note configurability * remove mention of vite * fix solve button styles * only add data-file attribute to files * separate routing and loading into separate sections, etc * remove $types, for now * move stuff * use a todo list example - better showcases PE, avoids complexity around user/session management * swap exercise order * flesh out form examples * move invalidation to advanced section * tweak page options docs * move * flesh out example to show use of page store etc * small tweaks * better redirects tutorial * move $page.X usage into second chapter * await parent * tweaks * better private env tutorials * get rid of VITE_ prefix * fix gitignore * remove logging * fix * fixes * invalid -> fail * robustify * rename section to the less-ambiguous "exercise" for my own sanity * allow an exercise to inherit files from previous exercises to reduce duplication * remove some now-unnecessary files * delete file * hide error customisation exercise for now - not ready to talk about hooks * update errors and redirects section * more detail * tweaks * add inspector * formatting * make "next" links more sensible * fix chaining logic * update optional params example * rest params example * different param matcher example * tidy up * move some content around * add placeholder chapters on hooks and stores * env var stuff * oops, didnt mean to add these * tweak * style tweaks * move filetree components to separate folder to ease future refactoring * tweaks * remove warning spiel * update deps * use a regex * Revert "use a regex" This reverts commit ac9f872. * try this instead * use +layout.server.js instead of tutorial.json * make typescript a bit less complainy * show current exercise in menu * refactor filetree stuff a bit * remove unused import * simplify file creation, always select newly created file * move icons * oops * derive depth at point of use * simplify renaming * simplify * refactor filetree * remove unused import * make editing constraints visible - is more accessible etc * use a store for filesystem state * make constraints more granular * DRY things out a bit * more DRYing out * insertion order * various fixes * a11y fix * fix * context menu styling * fixes * DRY out actions * fix * fix * fix * DRY out some more * refactor * split up env var exercises * fix * put <img> inside <button> * remove some unnecessary files * add route group example that includes a load function * shuffle things around a bit * make breakout example more visual * oops * bump kit * add way to relax file tree constraints * fix complete/reset state toggle * pretty sure we actually want to check in the lockfile * tweak * remove TODO * tweak example * demonstrate returning non-serializable data from load function * rename exercise to invalidation * show a case where one load is invalidated and one isnt * follow previous exercise, use generic data:blah key * follow previous exercise * add coming soon messages to get us off the hook for now * remove old TODO * work around hotlinking limitation * remove __hidden mechanism, its way too confusing. comment out this exercise until we can investigate truncated bodies * add some default styles etc * more tidying up * explain CSRF stuff Co-authored-by: Tan Li Hau <tanhauhau@users.noreply.github.com> Co-authored-by: Geoff Rich <4992896+geoffrich@users.noreply.github.com> Co-authored-by: Rich Harris <hello@rich-harris.dev> Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
1 parent 726013c commit 2ab9dba

File tree

277 files changed

+6395
-2082
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+6395
-2082
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
.env
77
.env.*
88
!.env.example
9+
!/content/tutorial/04-advanced-sveltekit/06-environment-variables/**/.env
910
.apps
1011
.vercel
1112
/content/tutorial/common/.svelte-kit
12-
/content/tutorial/common/node_modules
13-
/content/tutorial/common/package-lock.json
13+
/content/tutorial/common/node_modules

.prettierrc

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77
{
88
"files": ["content/**/*.svelte"],
99
"options": {
10-
"printWidth": 50,
10+
"printWidth": 70,
1111
"requirePragma": true
1212
}
13+
},
14+
{
15+
"files": ["content/**/*.js"],
16+
"options": {
17+
"printWidth": 70
18+
}
1319
}
1420
]
1521
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ The next steps depend on whether you want to run this locally in filesystem mode
2424

2525
## Creating new tutorials
2626

27-
Tutorials live inside `content`. Each tutorial consists of a `README.md`, which is the text to the left, and `app-a` and `app-b` folders, which represent the initial and solved state. Files that stay the same can be omitted from `app-b`. Files are marked as deleted in `app-b` if they start with `__delete`. Folders that are marked as deleted in `app-b` if they contain a file named `__delete`. Folders that contain a file named `__hidden` are not visible in the file tree.
27+
Tutorials live inside `content`. Each tutorial consists of a `README.md`, which is the text to the left, and `app-a` and `app-b` folders, which represent the initial and solved state. Files that stay the same can be omitted from `app-b`. Files are marked as deleted in `app-b` if they start with `__delete`. Folders that are marked as deleted in `app-b` if they contain a file named `__delete`.

content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
title: Welcome to Svelte
33
---
44

5-
> WARNING: this content is a work in progress and may be out of date. If you are learning Svelte, please refer to the [tutorial on svelte.dev](https://svelte.dev/tutorial) for now. If you are learning SvelteKit, refer to the [SvelteKit docs](https://kit.svelte.dev/docs).
6-
75
Welcome to the Svelte tutorial! This will teach you everything you need to know to easily build fast, small web applications.
86

97
You can also consult the [API docs](https://svelte.dev/docs) and the [examples](https://svelte.dev/examples), or — if you're impatient to start hacking on your machine locally — create a project with `npm init svelte`.
@@ -25,8 +23,8 @@ This tutorial is split into four main parts:
2523
- [Welcome to Svelte](/tutorial/welcome-to-svelte) (you are here)
2624
- [Introduction to SvelteKit](/tutorial/introducing-sveltekit)
2725
- [Advanced Svelte](/tutorial/tweens)
28-
- [Advanced SvelteKit](/tutorial/sandbox)
26+
- [Advanced SvelteKit](/tutorial/optional-params)
2927

30-
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.
28+
Each section will present an exercise designed to illustrate a feature. Later exercises 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.
3129

3230
If you get stuck, you can click the `solve` button to the left of the editor. (It's disabled on sections like this one that don't include an exercise.) Try not to rely on it too much; you will learn faster by figuring out where to put each suggested code block and manually typing it in to the editor.

content/tutorial/02-sveltekit/01-concepts/01-introducing-sveltekit/README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
title: What is SvelteKit?
33
---
44

5-
> 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).
6-
75
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.
86

97
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:
@@ -20,6 +18,6 @@ That's where SvelteKit comes in. Whereas Svelte is a _component framework_, Svel
2018
- Deploying to different hosting providers
2119
- ...and so on
2220

23-
It also provides a world-class development experience powered by [Vite](https://vitejs.dev). SvelteKit apps are server-rendered by default (like traditional 'multi-page apps' or MPAs) for excellent first load performance and SEO characteristics, but can then transition to client-side navigation (like modern 'single-page apps' or SPAs) to avoid jankily reloading everything (including things like third-party analytics code) when the user navigates. They can run anywhere JavaScript runs, though — as we'll see — your users may not need to run any JavaScript at all.
21+
SvelteKit apps are server-rendered by default (like traditional 'multi-page apps' or MPAs) for excellent first load performance and SEO characteristics, but can then transition to client-side navigation (like modern 'single-page apps' or SPAs) to avoid jankily reloading everything (including things like third-party analytics code) when the user navigates. They can run anywhere JavaScript runs, though — as we'll see — your users may not need to run any JavaScript at all.
2422

2523
If that sounds complicated, worry not: you've been using SvelteKit this whole time!

content/tutorial/02-sveltekit/01-concepts/02-project-structure/app-a/src/routes/+page.svelte

-1
This file was deleted.

content/tutorial/02-sveltekit/01-concepts/03-server-and-client/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ A SvelteKit app can be thought of as two distinct entities working in tandem —
88

99
'Client' refers to the JavaScript that loads in the browser.
1010

11-
TODO
11+
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.
12+
13+
> You can [adjust this behavior](https://kit.svelte.dev/docs/page-options) as needed. SvelteKit is very versatile!

content/tutorial/02-sveltekit/01-concepts/03-server-and-client/app-a/src/routes/+page.svelte

-1
This file was deleted.

content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/README.md

-5
This file was deleted.

content/tutorial/02-sveltekit/01-concepts/04-server-side-rendering/app-a/src/routes/+page.svelte

-1
This file was deleted.

content/tutorial/02-sveltekit/01-concepts/05-prerendering/README.md

-5
This file was deleted.

content/tutorial/02-sveltekit/01-concepts/05-prerendering/app-a/src/routes/+page.svelte

-1
This file was deleted.

content/tutorial/02-sveltekit/02-routing/01-pages/README.md

+14-4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ title: Pages
44

55
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.
66

7-
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.
7+
The routes are located within `src/routes`. Every directory within which contains a `+page.svelte` file creates a route in your app.
88

9-
> 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.
9+
In this app we currently have one route — `src/routes/+page.svelte`, which maps to `/`.
1010

11-
Let's add a link in `src/routes/about/+page.svelte` back to the homepage:
11+
Let's add a second route, `src/routes/about/+page.svelte`, which maps to `/about`:
1212

1313
```svelte
14+
/// file: src/routes/about/+page.svelte
15+
<nav>
16+
<a href="/">Home</a>
17+
<a href="/about">About</a>
18+
</nav>
19+
20+
<h1>About</h1>
1421
<p>This is the about page.</p>
15-
<p>Go to the +++<a href="/">+++home+++</a>+++ page</p>
1622
```
23+
24+
We can now navigate between `/` and `/about`.
25+
26+
> 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. (This behaviour can be [configured](https://kit.svelte.dev/docs/page-options).)

content/tutorial/02-sveltekit/02-routing/01-pages/app-a/src/routes/+page.svelte

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<h1>Home</h1>
1+
<nav>
2+
<a href="/">Home</a>
3+
<a href="/about">About</a>
4+
</nav>
25

6+
<h1>Home</h1>
37
<p>This is the home page.</p>
4-
<p>Go to the <a href="/about">about</a> page.</p>

content/tutorial/02-sveltekit/02-routing/01-pages/app-b/src/routes/about/+page.svelte

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<h1>About</h1>
1+
<nav>
2+
<a href="/">Home</a>
3+
<a href="/about">About</a>
4+
</nav>
25

6+
<h1>About</h1>
37
<p>This is the about page.</p>
4-
<p>Go to the <a href="/">home</a> page</p>

content/tutorial/02-sveltekit/02-routing/02-endpoints/README.md

-5
This file was deleted.

content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/+page.svelte

-4
This file was deleted.

content/tutorial/02-sveltekit/02-routing/02-endpoints/app-a/src/routes/about/+page.svelte

-4
This file was deleted.

content/tutorial/02-sveltekit/02-routing/02-endpoints/app-b/src/routes/about/+page.svelte

-4
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Layouts
3+
---
4+
5+
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.
6+
7+
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`...
8+
9+
```diff
10+
src/routes/
11+
├ about/
12+
│ └ +page.svelte
13+
+├ +layout.svelte
14+
└ +page.svelte
15+
```
16+
17+
...and move the duplicated content from the `+page.svelte` files into the new `+layout.svelte` file. The `<slot />` element is where the page content will be rendered:
18+
19+
```svelte
20+
/// file: src/routes/about/+page.svelte
21+
<nav>
22+
<a href="/">Home</a>
23+
<a href="/about">About</a>
24+
</nav>
25+
26+
<slot />
27+
```
28+
29+
A `+layout.svelte` file applies to every child route, including the sibling `+page.svelte` (if it exists). You can nest layouts to arbitrary depth.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<nav>
2+
<a href="/">Home</a>
3+
<a href="/about">About</a>
4+
</nav>
5+
6+
<slot />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<h1>Home</h1>
2+
<p>This is the home page.</p>
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
<h1>About</h1>
2-
32
<p>This is the about page.</p>
4-
<p>Go to the home page</p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
title: Route parameters
3+
---
4+
5+
To create routes with dynamic parameters, use square brackets around a valid variable name. For example, a file like `src/routes/blog/[slug]/+page.svelte` will create a route that matches `/blog/one`, `/blog/two`, `/blog/three` and so on.
6+
7+
Let's create that file:
8+
9+
```svelte
10+
/// file: src/routes/blog/[slug]/+page.svelte
11+
<h1>Blog post</h1>
12+
```
13+
14+
We can now navigate from the `/blog` page to individual blog posts. In the next chapter, we'll see how to load their content.
15+
16+
> 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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<nav>
2+
<a href="/">Home</a>
3+
<a href="/blog">Blog</a>
4+
</nav>
5+
6+
<slot />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Home Page</p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<h1>Blog</h1>
2+
3+
<ul>
4+
<li><a href="/blog/one">one</a></li>
5+
<li><a href="/blog/two">two</a></li>
6+
<li><a href="/blog/three">three</a></li>
7+
</ul>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>Blog post</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
title: Page data
3+
---
4+
5+
At its core, SvelteKit's job boils down to three things:
6+
7+
1. **Routing** — figure out which route matches an incoming request
8+
2. **Loading** — get the data needed by the route
9+
3. **Rendering** - generate some HTML (on the server) or update the DOM (in the browser)
10+
11+
We've seen how routing and rendering work. Let's talk about the middle part — loading.
12+
13+
Every page of your app can declare a `load` function in a `+page.server.js` file alongside the `+page.svelte` file. As the file name suggests, this module only ever runs on the server, including for client-side navigations. Let's add a `src/routes/blog/+page.server.js` file so that we can replace the hard-coded links in `src/routes/blog/+page.svelte` with actual blog post data:
14+
15+
```js
16+
/// file: src/routes/blog/+page.server.js
17+
import { posts } from './data.js';
18+
19+
export function load() {
20+
return {
21+
summaries: posts.map((post) => ({
22+
slug: post.slug,
23+
title: post.title
24+
}))
25+
};
26+
}
27+
```
28+
29+
> For the sake of the tutorial, we're importing data from `src/routes/blog/data.js`. In a real app, you'd be more likely to load the data from a database or a CMS, but for now we'll do it like this.
30+
31+
We can access this data in `src/routes/blog/+page.svelte` via the `data` prop:
32+
33+
```svelte
34+
+++<script>
35+
export let data;
36+
</script>+++
37+
38+
<h1>Blog</h1>
39+
40+
<ul>
41+
--- <li><a href="/blog/one">one</a></li>
42+
<li><a href="/blog/two">two</a></li>
43+
<li><a href="/blog/three">three</a></li>---
44+
+++ {#each data.summaries as { slug, title }}
45+
<li><a href="/blog/{slug}">{title}</a></li>
46+
{/each}+++
47+
</ul>
48+
```
49+
50+
Now, let's do the same for the post page:
51+
52+
```js
53+
/// file: src/routes/blog/[slug]/+page.server.js
54+
import { posts } from '../data.js';
55+
56+
export function load({ params }) {
57+
const post = posts.find((post) => post.slug === params.slug);
58+
59+
return {
60+
post
61+
};
62+
}
63+
```
64+
65+
```svelte
66+
/// file: src/routes/blog/[slug]/+page.svelte
67+
+++<script>
68+
export let data;
69+
</script>+++
70+
71+
---<h1>Blog post</h1>---
72+
+++<h1>{data.post.title}</h1>
73+
<div>{@html data.post.content}</div>+++
74+
```
75+
76+
There's one last detail we need to take care of — the user might visit an invalid pathname like `/blog/nope`, in which case we'd like to respond with a 404 page:
77+
78+
```js
79+
/// file: src/routes/blog/[slug]/+page.server.js
80+
+++import { error } from '@sveltejs/kit';+++
81+
import { posts } from '../data.js';
82+
83+
export function load({ params }) {
84+
const post = posts.find((post) => post.slug === params.slug);
85+
86+
+++if (!post) throw error(404);+++
87+
88+
return {
89+
post
90+
};
91+
}
92+
```
93+
94+
We'll learn more about error handling in later chapters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<nav>
2+
<a href="/">Home</a>
3+
<a href="/blog">Blog</a>
4+
</nav>
5+
6+
<slot />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Home Page</p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<h1>Blog</h1>
2+
3+
<ul>
4+
<li><a href="/blog/one">one</a></li>
5+
<li><a href="/blog/two">two</a></li>
6+
<li><a href="/blog/three">three</a></li>
7+
</ul>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>Blog post</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export const posts = [
2+
{
3+
slug: 'welcome',
4+
title: 'Welcome to the Aperture Science computer-aided enrichment center',
5+
content:
6+
'<p>We hope your brief detention in the relaxation vault has been a pleasant one.</p><p>Your specimen has been processed and we are now ready to begin the test proper.</p>'
7+
},
8+
9+
{
10+
slug: 'safety',
11+
title: 'Safety notice',
12+
content:
13+
'<p>While safety is one of many Enrichment Center Goals, the Aperture Science High Energy Pellet, seen to the left of the chamber, can and has caused permanent disabilities, such as vaporization. Please be careful.</p>'
14+
},
15+
16+
{
17+
slug: 'cake',
18+
title: 'This was a triumph',
19+
content: "<p>I'm making a note here: HUGE SUCCESS.</p>"
20+
}
21+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { posts } from './data.js';
2+
3+
export function load() {
4+
return {
5+
summaries: posts.map((post) => ({
6+
slug: post.slug,
7+
title: post.title
8+
}))
9+
};
10+
}

0 commit comments

Comments
 (0)