## tutorial/index.md
--- title: Tutorial ---
## tutorial/01-svelte/index.md
--- title: Basic Svelte label: Part 1 scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte ---
## tutorial/01-svelte/01-introduction/index.md
--- title: Introduction scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte ---
## tutorial/01-svelte/01-introduction/01-welcome-to-svelte/index.md
--- title: Welcome to Svelte --- Welcome to the Svelte tutorial! This will teach you everything you need to know to easily build web applications of all sizes, with high performance and a small footprint. You can also consult the [API docs](https://svelte.dev/docs) and visit the [playground](https://svelte.dev/playground), or — if you're impatient to start hacking on your machine locally — create a project with `npx sv create`. ## What is Svelte? Svelte is a tool for building web applications. Like other user interface frameworks, it allows you to build your app _declaratively_ out of components that combine markup, styles and behaviours. These components are _compiled_ into small, efficient JavaScript modules that eliminate overhead traditionally associated with UI frameworks. You can build your entire app with Svelte (for example, using an application framework like [SvelteKit](/docs/kit), which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere. ## How to use this tutorial This tutorial is split into four main parts: - [Basic Svelte](/tutorial/svelte/welcome-to-svelte) (you are here) - [Advanced Svelte](/tutorial/svelte/tweens) - [Basic SvelteKit](/tutorial/kit/introducing-sveltekit) - [Advanced SvelteKit](/tutorial/kit/optional-params) 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. If you get stuck, you can click the `solve` button in the top right of the screen. (The `solve` button is 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.
## tutorial/01-svelte/01-introduction/02-your-first-component/index.md
--- title: Your first component --- In Svelte, an application is composed from one or more _components_. A component is a reusable self-contained block of code that encapsulates HTML, CSS and JavaScript that belong together, written into a `.svelte` file. The `App.svelte` file, open in the code editor to the right, is a simple component. ## Adding data A component that just renders some static markup isn't very interesting. Let's add some data. First, add a script tag to your component and declare a `name` variable: ```svelte /// file: App.svelte
Hello world!
``` Then, we can refer to `name` in the markup: ```svelte /// file: App.svelte
Hello{name}!
``` Inside the curly braces, we can put any JavaScript we want. Try changing `name` to `name.toUpperCase()` for a shoutier greeting. ```svelte /// file: App.svelte
Hello {name.toUpperCase()}!
```
## tutorial/01-svelte/01-introduction/03-dynamic-attributes/index.md
--- title: Dynamic attributes --- Just like you can use curly braces to control text, you can use them to control element attributes. Our image is missing a `src` — let's add one: ```svelte /// file: App.svelte ``` That's better. But if you hover over the `` in the editor, Svelte is giving us a warning: ``` `` element should have an alt attribute ``` When building web apps, it's important to make sure that they're _accessible_ to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup. In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one: ```svelte /// file: App.svelte ``` We can use curly braces _inside_ attributes. Try changing it to `"{name} dances."` — remember to declare a `name` variable in the ` ``` ...and include a `` component: ```svelte /// file: App.svelte
This is a paragraph.
``` Notice that even though `Nested.svelte` has a `
` element, the styles from `App.svelte` don't leak in.
## tutorial/01-svelte/01-introduction/06-html-tags/index.md
--- title: HTML tags --- Ordinarily, strings are inserted as plain text, meaning that characters like `<` and `>` have no special meaning. But sometimes you need to render HTML directly into a component. For example, the words you're reading right now exist in a markdown file that gets included on this page as a blob of HTML. In Svelte, you do this with the special `{@html ...}` tag: ```svelte /// file: App.svelte
{@htmlstring}
```
## tutorial/01-svelte/02-reactivity/index.md
--- title: Reactivity scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte ---
## tutorial/01-svelte/02-reactivity/01-state/index.md
--- title: State --- At the heart of Svelte is a powerful system of _reactivity_ for keeping the DOM in sync with your application state — for example, in response to an event. Make the `count` declaration reactive by wrapping the value with `$state(...)`: ```js /// file: App.svelte let count =$state(0); ``` This is called a _rune_, and it's how you tell Svelte that `count` isn't an ordinary variable. Runes look like functions, but they're not — when you use Svelte, they're part of the language itself. All that's left is to implement `increment`: ```js /// file: App.svelte function increment() { count += 1; } ```
## tutorial/01-svelte/02-reactivity/02-deep-state/index.md
--- title: Deep state --- As we saw in the previous exercise, state reacts to _reassignments_. But it also reacts to _mutations_ — we call this _deep reactivity_. Make `numbers` a reactive array: ```js /// file: App.svelte let numbers =$state([1, 2, 3, 4]); ``` Now, when we change the array... ```js /// file: App.svelte function addNumber() { numbers[numbers.length] = numbers.length + 1; } ``` ...the component updates. Or better still, we can `push` to the array instead: ```js /// file: App.svelte function addNumber() { numbers.push(numbers.length + 1); } ```
## tutorial/01-svelte/02-reactivity/03-derived-state/index.md
--- title: Derived state --- Often, you will need to _derive_ state from other state. For this, we have the `$derived` rune: ```js /// file: App.svelte let numbers = $state([1, 2, 3, 4]); let total = $derived(numbers.reduce((t, n) => t + n, 0)); ``` We can now use this in our markup: ```svelte /// file: App.svelte
{numbers.join(' + ')} ={total}
``` The expression inside the `$derived` declaration will be re-evaluated whenever its dependencies (in this case, just `numbers`) are updated. Unlike normal state, derived state is read-only.
## tutorial/01-svelte/02-reactivity/04-inspecting-state/index.md
--- title: Inspecting state --- It's often useful to be able to track the value of a piece of state as it changes over time. Inside the `addNumber` function, we've added a `console.log` statement. But if you click the button and open the console drawer (using the button to the right of the URL bar), you'll see a warning, and a message saying the message could not be cloned. That's because `numbers` is a reactive [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). There are a couple of things we can do. Firstly, we can create a non-reactive _snapshot_ of the state with `$state.snapshot(...)`: ```js /// file: App.svelte function addNumber() { numbers.push(numbers.length + 1); console.log($state.snapshot(numbers)); } ``` Alternatively, we can use the `$inspect` rune to automatically log a snapshot of the state whenever it changes. This code will automatically be stripped out of your production build: ```js /// file: App.svelte function addNumber() { numbers.push(numbers.length + 1); console.log($state.snapshot(numbers)); } $inspect(numbers); ``` You can customise how the information is displayed by using `$inspect(...).with(fn)` — for example, you can use `console.trace` to see where the state change originated from: ```js /// file: App.svelte $inspect(numbers).with(console.trace); ```
## tutorial/01-svelte/02-reactivity/05-effects/index.md
--- title: Effects --- So far we've talked about reactivity in terms of state. But that's only half of the equation — state is only reactive if something is _reacting_ to it, otherwise it's just a sparkling variable. The thing that reacts is called an _effect_. You've already encountered effects — the ones that Svelte creates on your behalf to update the DOM in response to state changes — but you can also create your own with the `$effect` rune. Let's say we want to use `setInterval` to keep track of how long the component has been mounted. Create the effect: ```svelte /// file: App.svelte ``` Click the 'speed up' button a few times and notice that `elapsed` ticks up faster, because we're calling `setInterval` each time `interval` gets smaller. If we then click the 'slow down' button... well, it doesn't work. That's because we're not clearing out the old intervals when the effect updates. We can fix that by returning a cleanup function: ```js /// file: App.svelte $effect(() => { const id =setInterval(() => { elapsed += 1; }, interval); return () => { clearInterval(id); }; }); ``` The cleanup function is called immediately before the effect function re-runs when `interval` changes, and also when the component is destroyed. If the effect function doesn't read any state when it runs, it will only run once, when the component mounts.
## tutorial/01-svelte/02-reactivity/06-universal-reactivity/index.md
--- title: Universal reactivity --- In the preceding exercises, we used runes to add reactivity inside components. But we can also use runes _outside_ components, for example to share some global state. The `` components in this exercise are all importing the `counter` object from `shared.js`. But it's a normal object, and as such nothing happens when you click the buttons. Wrap the object in `$state(...)`: ```js /// file: shared.js export const counter =$state({ count: 0 }); ``` This causes an error, because you can't use runes in normal `.js` files, only `.svelte.js` files. Let's fix that — rename the file to `shared.svelte.js`. Then, update the import declaration in `Counter.svelte`: ```svelte /// file: Counter.svelte ``` Now, when you click any button, all three update simultaneously.
## tutorial/01-svelte/03-props/index.md
--- title: Props scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte ---
## tutorial/01-svelte/03-props/01-declaring-props/index.md
--- title: Declaring props --- So far, we've dealt exclusively with internal state — that is to say, the values are only accessible within a given component. In any real application, you'll need to pass data from one component down to its children. To do that, we need to declare _properties_, generally shortened to 'props'. In Svelte, we do that with the `$props` rune. Edit the `Nested.svelte` component: ```svelte /// file: Nested.svelte ```
## tutorial/01-svelte/03-props/02-default-values/index.md
--- title: Default values --- We can easily specify default values for props in `Nested.svelte`: ```svelte /// file: Nested.svelte ``` If we now add a second component _without_ an `answer` prop, it will fall back to the default: ```svelte /// file: App.svelte ```
## tutorial/01-svelte/03-props/03-spread-props/index.md
--- title: Spread props --- In this exercise, in `App.svelte` we've forgotten to pass the `name` prop expected by `PackageInfo.svelte`, meaning the `` element is empty and the npm link is broken. We _could_ fix it by adding the prop... ```svelte /// file: App.svelte ``` ...but since the properties of `pkg` correspond to the component's expected props, we can 'spread' them onto the component instead: ```svelte /// file: App.svelte ``` > > ```js > let { name, ...stuff } = $props(); > ``` > > ...or by skipping [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) altogether: > > ```js > let stuff = $props(); > ``` > > ...in which case you can access the properties by their object paths: > > ```js > console.log(stuff.name, stuff.version, stuff.description, stuff.website); > ```
## tutorial/01-svelte/04-logic/index.md
--- title: Logic scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte ---
## tutorial/01-svelte/04-logic/01-if-blocks/index.md
--- title: If blocks --- HTML doesn't have a way of expressing _logic_, like conditionals and loops. Svelte does. To conditionally render some markup, we wrap it in an `if` block. Let's add some text that appears when `count` is greater than `10`: ```svelte /// file: App.svelte {#if count > 10}
{count} is greater than 10
{/if} ``` Try it — update the component, and click on the button a few times.
## tutorial/01-svelte/04-logic/02-else-blocks/index.md
--- title: Else blocks --- Just like in JavaScript, an `if` block can have an `else` block: ```svelte /// file: App.svelte {#if count > 10}
{count} is greater than 10
{:else}
{count} is between 0 and 10
{/if} ``` `{#...}` opens a block. `{/...}` closes a block. `{:...}` _continues_ a block. Congratulations — you've already learned almost all the syntax Svelte adds to HTML.
## tutorial/01-svelte/04-logic/03-else-if-blocks/index.md
--- title: Else-if blocks --- Multiple conditions can be 'chained' together with `else if`: ```svelte /// file: App.svelte {#if count > 10}
{count} is greater than 10
{:else if count < 5}
{count} is less than 5
{:else}
{count} is between5and 10
{/if} ```
## tutorial/01-svelte/04-logic/04-each-blocks/index.md
--- title: Each blocks --- When building user interfaces you'll often find yourself working with lists of data. In this exercise, we've repeated the `