## 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 ` {/each} ``` Now we need to use the `color` variable in place of `"red"`: ```svelte /// file: App.svelte
{#each colors as color} {/each}
``` You can get the current _index_ as a second argument, like so: ```svelte /// file: App.svelte
{#each colors as color,i} {/each}
``` ## tutorial/01-svelte/04-logic/05-keyed-each-blocks/index.md --- title: Keyed each blocks --- By default, when you modify the value of an `each` block, it will add and remove DOM nodes at the _end_ of the block, and update any values that have changed. That might not be what you want. It's easier to show why than to explain. Inside `Thing.svelte`, `name` is a dynamic prop but `emoji` is a constant. Click the 'Remove first thing' button a few times, and notice what happens: 1. It removes the last component. 2. It then updates the `name` value in the remaining DOM nodes, but not the emoji. One way to fix it would be to make `emoji` a [`$derived`](derived-state) value. But it makes more sense to remove the first `` component altogether than to remove the _last_ one and update all the others. To do that, we specify a unique _key_ for each iteration of the `each` block: ```svelte /// file: App.svelte {#each things as thing (thing.id)} {/each} ``` ## tutorial/01-svelte/04-logic/06-await-blocks/index.md --- title: Await blocks --- Most web applications have to deal with asynchronous data at some point. Svelte makes it easy to _await_ the value of [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) directly in your markup: ```svelte /// file: App.svelte {#await promise}

...rolling

{:then number}

you rolled a {number}!

{:catch error}

{error.message}

{/await} ``` If you know that your promise can't reject, you can omit the `catch` block. You can also omit the first block if you don't want to show anything until the promise resolves: ```svelte {#await promise then number}

you rolled a {number}!

{/await} ``` ## tutorial/01-svelte/05-events/index.md --- title: Events scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte --- ## tutorial/01-svelte/05-events/01-dom-events/index.md --- title: DOM events --- As we've briefly seen already, you can listen to any DOM event on an element (such as click or [pointermove](https://developer.mozilla.org/en-US/docs/Web/API/Element/pointermove_event)) with an `on` function: ```svelte /// file: App.svelte The pointer is at {Math.round(m.x)} x {Math.round(m.y)} ``` Like with any other property where the name matches the value, we can use the short form: ```svelte /// file: App.svelte The pointer is at {Math.round(m.x)} x {Math.round(m.y)} ``` ## tutorial/01-svelte/05-events/02-inline-handlers/index.md --- title: Inline handlers --- You can also declare event handlers inline: ```svelte /// file: App.svelte
{ m.x = event.clientX; m.y = event.clientY; }} > The pointer is at {m.x} x {m.y}
``` ## tutorial/01-svelte/05-events/03-capturing/index.md --- title: Capturing --- Normally, event handlers run during the [_bubbling_](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Event_bubbling) phase. Notice what happens if you type something into the `` in this example — the inner handler runs first, as the event 'bubbles' from the target up to the document, followed by the outer handler. Sometimes, you want handlers to run during the _capture_ phase instead. Add `capture` to the end of the event name: ```svelte /// file: App.svelte
alert(`
${e.key}`)} role="presentation"> alert(` ${e.key}`)} />
``` Now, the relative order is reversed. If both capturing and non-capturing handlers exist for a given event, the capturing handlers will run first. ## tutorial/01-svelte/05-events/04-component-events/index.md --- title: Component events --- You can pass event handlers to components like any other prop. In `Stepper.svelte`, add `increment` and `decrement` props... ```svelte /// file: Stepper.svelte ``` ...and wire them up: ```svelte /// file: Stepper.svelte -1 +1 ``` In `App.svelte`, define the handlers: ```svelte value += 1} decrement={() => value -= 1} /> ``` ## tutorial/01-svelte/05-events/05-spreading-events/index.md --- title: Spreading events --- We can also [spread](spread-props) event handlers directly onto elements. Here, we've defined an `onclick` handler in `App.svelte` — all we need to do is pass the props to the ` ``` ## tutorial/01-svelte/06-bindings/index.md --- title: Bindings scope: { 'prefix': '/src/lib/', 'name': 'src' } focus: /src/lib/App.svelte --- ## tutorial/01-svelte/06-bindings/01-text-inputs/index.md --- title: Text inputs --- As a general rule, data flow in Svelte is _top down_ — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around. Sometimes it's useful to break that rule. Take the case of the `` element in this component — we _could_ add an `oninput` event handler that sets the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other form elements, as we'll see. Instead, we can use the `bind:value` directive: ```svelte /// file: App.svelte ``` This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`. ## tutorial/01-svelte/06-bindings/02-numeric-inputs/index.md --- title: Numeric inputs --- In the DOM, every input value is a string. That's unhelpful when you're dealing with numeric inputs — `type="number"` and `type="range"` — as it means you have to remember to coerce `input.value` before using it. With `bind:value`, Svelte takes care of it for you: ```svelte /// file: App.svelte ``` ## tutorial/01-svelte/06-bindings/03-checkbox-inputs/index.md --- title: Checkbox inputs --- Checkboxes are used for toggling between states. Instead of binding to `input.value`, we bind to `input.checked`: ```svelte /// file: App.svelte ``` ## tutorial/01-svelte/06-bindings/04-select-bindings/index.md --- title: Select bindings --- We can also use `bind:value` with ` answer = ''} > ``` Note that the `