Skip to content

Commit 0e0d6ed

Browse files
Sync svelte docs (#1196)
sync svelte docs Co-authored-by: svelte-docs-bot[bot] <196124396+svelte-docs-bot[bot]@users.noreply.github.com>
1 parent a324f57 commit 0e0d6ed

File tree

5 files changed

+161
-132
lines changed

5 files changed

+161
-132
lines changed

apps/svelte.dev/content/docs/svelte/02-runes/04-$effect.md

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -281,62 +281,34 @@ You might be tempted to do something convoluted with effects to link one value t
281281
</label>
282282
```
283283

284-
Instead, use callbacks where possible ([demo](/playground/untitled#H4sIAAAAAAAACo1SMW6EMBD8imWluFMSIEUaDiKlvy5lSOHjlhOSMRZeTiDkv8deMEEJRcqdmZ1ZjzzxqpZgePo5cRw18JQA_sSVaPz0rnVk7iDRYxdhYA8vW4Wg0NnwzJRdrfGtUAVKQIYtCsly9pIkp4AZ7cQOezAoEA7JcWUkVBuCdol0dNWrEutWsV5fHfnhPQ5wZJMnCwyejxCh6G6A0V3IHk4zu_jOxzzPBxBld83PTr7xXrb3rUNw8PbiYJ3FP22oTIoLSComq5XuXTeu8LzgnVA3KDgj13wiQ8taRaJ82rzXskYM-URRlsXktejjgNLoo9e4fyf70_8EnwncySX1GuunX6kGRwnzR_BgaPNaGy3FmLJKwrCUeBM6ZUn0Cs2mOlp3vwthQJ5i14P9st9vZqQlsQIAAA==)):
284+
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE51SsW6DMBT8FcvqABINdOhCIFKXTt06lg4GHpElYyz8iECIf69tcIIipo6-u3f3fPZMJWuBpvRzkBXyTpKSy5rLq6YRbbgATdOfmeKkrMgCBt9GPpQ66RsItFjJNBzhVScRJBobmumq5wovhSxQABLskAmSk7ckOXtMKyM22ItGhhAk4Z0R0OwIN-tIQzd-90HVhvy2HsGNiQFCMltBgd7XoecV2xzXNV7XaEcth7ZfRv7kujnsTX2Qd7USb5rFjwZkJlgJwpWRcakG04cpOS9oz-QVCuoeInXW-RyEJL-sG0b7Wy6kZWM-u7CFxM5tdrIl9qg72vB74H-y7T2iXROHyVb0CLanp1yNk4D1A1jQ91hzrQSbUtIIGLcir0ylJDm9Q7urz42bX4UwIk2xH2D5Xf4A7SeMcMQCAAA=)):
285285

286286
```svelte
287287
<script>
288288
let total = 100;
289289
let spent = $state(0);
290290
let left = $state(total);
291291
292-
function updateSpent(e) {
293-
spent = +e.target.value;
292+
function updateSpent(value) {
293+
spent = value;
294294
left = total - spent;
295295
}
296296
297-
function updateLeft(e) {
298-
left = +e.target.value;
297+
function updateLeft(value) {
298+
left = value;
299299
spent = total - left;
300300
}
301301
</script>
302302
303303
<label>
304-
<input type="range" value={spent} oninput={updateSpent} max={total} />
304+
<input type="range" bind:value={() => spent, updateSpent} max={total} />
305305
{spent}/{total} spent
306306
</label>
307307
308308
<label>
309-
<input type="range" value={left} oninput={updateLeft} max={total} />
309+
<input type="range" bind:value={() => left, updateLeft} max={total} />
310310
{left}/{total} left
311311
</label>
312312
```
313313

314-
If you need to use bindings, for whatever reason (for example when you want some kind of "writable `$derived`"), consider using getters and setters to synchronise state ([demo](/playground/untitled#H4sIAAAAAAAACpWRwW6DMBBEf8WyekikFOihFwcq9TvqHkyyQUjGsfCCQMj_XnvBNKpy6Qn2DTOD1wu_tRocF18Lx9kCFwT4iRvVxenT2syNoDGyWjl4xi93g2AwxPDSXfrW4oc0EjUgwzsqzSr2VhTnxJwNHwf24lAhHIpjVDZNwy1KS5wlNoGMSg9wOCYksQccerMlv65p51X0p_Xpdt_4YEy9yTkmV3z4MJT579-bUqsaNB2kbI0dwlnCgirJe2UakJzVrbkKaqkWivasU1O1ULxnOVk3JU-Uxti0p_-vKO4no_enbQ_yXhnZn0aHs4b1jiJMK7q2zmo1C3bTMG3LaZQVrMjeoSPgaUtkDxePMCEX2Ie6b_8D4WyJJEwCAAA=)):
315-
316-
```svelte
317-
<script>
318-
let total = 100;
319-
let spent = $state(0);
320-
321-
let left = {
322-
get value() {
323-
return total - spent;
324-
},
325-
set value(v) {
326-
spent = total - v;
327-
}
328-
};
329-
</script>
330-
331-
<label>
332-
<input type="range" bind:value={spent} max={total} />
333-
{spent}/{total} spent
334-
</label>
335-
336-
<label>
337-
<input type="range" bind:value={left.value} max={total} />
338-
{left.value}/{total} left
339-
</label>
340-
```
341-
342314
If you absolutely have to update `$state` within an effect and run into an infinite loop because you read and write to the same `$state`, use [untrack](svelte#untrack).

apps/svelte.dev/content/docs/svelte/06-runtime/02-context.md

Lines changed: 86 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,129 +3,137 @@ NOTE: do not edit this file, it is generated in apps/svelte.dev/scripts/sync-doc
33
title: Context
44
---
55

6-
<!-- - get/set/hasContext
7-
- how to use, best practises (like encapsulating them) -->
6+
Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as 'prop-drilling'). The parent component sets context with `setContext(key, value)`...
87

9-
Most state is component-level state that lives as long as its component lives. There's also section-wide or app-wide state however, which also needs to be handled somehow.
10-
11-
The easiest way to do that is to create global state and just import that.
8+
```svelte
9+
<!--- file: Parent.svelte --->
10+
<script>
11+
import { setContext } from 'svelte';
1212
13-
```ts
14-
/// file: state.svelte.js
15-
export const myGlobalState = $state({
16-
user: {
17-
/* ... */
18-
}
19-
/* ... */
20-
});
13+
setContext('my-context', 'hello from Parent.svelte');
14+
</script>
2115
```
2216

17+
...and the child retrieves it with `getContext`:
18+
2319
```svelte
24-
<!--- file: App.svelte --->
20+
<!--- file: Child.svelte --->
2521
<script>
26-
import { myGlobalState } from './state.svelte.js';
27-
// ...
22+
import { getContext } from 'svelte';
23+
24+
const message = getContext('my-context');
2825
</script>
26+
27+
<h1>{message}, inside Child.svelte</h1>
2928
```
3029

31-
This has a few drawbacks though:
30+
This is particularly useful when `Parent.svelte` is not directly aware of `Child.svelte`, but instead renders it as part of a `children` [snippet](snippet) ([demo](/playground/untitled#H4sIAAAAAAAAE42Q3W6DMAyFX8WyJgESK-oto6hTX2D3YxcM3IIUQpR40yqUd58CrCXsp7tL7HNsf2dAWXaEKR56yfTBGOOxFWQwfR6Qz8q1XAHjL-GjUhvzToJd7bU09FO9ctMkG0wxM5VuFeeFLLjtVK8ZnkpNkuGo-w6CTTJ9Z3PwsBAemlbUF934W8iy5DpaZtOUcU02-ZLcaS51jHEkTFm_kY1_wfOO8QnXrb8hBzDEc6pgZ4gFoyz4KgiD7nxfTe8ghqAhIfrJ46cTzVZBbkPlODVJsLCDO6V7ZcJoncyw1yRr0hd1GNn_ZbEM3I9i1bmVxOlWElUvDUNHxpQngt3C4CXzjS1rtvkw22wMrTRtTbC8Lkuabe7jvthPPe3DofYCAAA=)):
31+
32+
```svelte
33+
<Parent>
34+
<Child />
35+
</Parent>
36+
```
3237

33-
- it only safely works when your global state is only used client-side - for example, when you're building a single page application that does not render any of your components on the server. If your state ends up being managed and updated on the server, it could end up being shared between sessions and/or users, causing bugs
34-
- it may give the false impression that certain state is global when in reality it should only used in a certain part of your app
38+
The key (`'my-context'`, in the example above) and the context itself can be any JavaScript value.
3539

36-
To solve these drawbacks, Svelte provides a few `context` primitives which alleviate these problems.
40+
In addition to [`setContext`](svelte#setContext) and [`getContext`](svelte#getContext), Svelte exposes [`hasContext`](svelte#hasContext) and [`getAllContexts`](svelte#getAllContexts) functions.
3741

38-
## Setting and getting context
42+
## Using context with state
3943

40-
To associate an arbitrary object with the current component, use `setContext`.
44+
You can store reactive state in context ([demo](/playground/untitled#H4sIAAAAAAAAE41R0W6DMAz8FSuaBNUQdK8MkKZ-wh7HHihzu6hgosRMm1D-fUpSVNq12x4iEvvOx_kmQU2PIhfP3DCCJGgHYvxkkYid7NCI_GUS_KUcxhVEMjOelErNB3bsatvG4LW6n0ZsRC4K02qpuKqpZtmrQTNMYJA3QRAs7PTQQxS40eMCt3mX3duxnWb-lS5h7nTI0A4jMWoo4c44P_Hku-zrOazdy64chWo-ScfRkRgl8wgHKrLTH1OxHZkHgoHaTraHcopXUFYzPPVfuC_hwQaD1GrskdiNCdQwJljJqlvXfyqVsA5CGg0uRUQifHw56xFtciO75QrP07vo_JXf_tf8yK2ezDKY_ZWt_1y2qqYzv7bI1IW1V_sN19m-07wCAAA=))...
4145

4246
```svelte
4347
<script>
4448
import { setContext } from 'svelte';
49+
import Child from './Child.svelte';
4550
46-
setContext('key', value);
51+
let counter = $state({
52+
count: 0
53+
});
54+
55+
setContext('counter', counter);
4756
</script>
57+
58+
<button onclick={() => counter.count += 1}>
59+
increment
60+
</button>
61+
62+
<Child />
63+
<Child />
64+
<Child />
4865
```
4966

50-
The context is then available to children of the component (including slotted content) with `getContext`.
67+
...though note that if you _reassign_ `counter` instead of updating it, you will 'break the link' — in other words instead of this...
5168

5269
```svelte
53-
<script>
54-
import { getContext } from 'svelte';
55-
56-
const value = getContext('key');
57-
</script>
70+
<button onclick={() => counter = { count: 0 }}>
71+
reset
72+
</button>
5873
```
5974

60-
`setContext` and `getContext` solve the above problems:
75+
...you must do this:
6176

62-
- the state is not global, it's scoped to the component. That way it's safe to render your components on the server and not leak state
63-
- it's clear that the state is not global but rather scoped to a specific component tree and therefore can't be used in other parts of your app
77+
```svelte
78+
<button onclick={() => +++counter.count = 0+++}>
79+
reset
80+
</button>
81+
```
6482

65-
> [!NOTE] `setContext`/`getContext` must be called during component initialisation.
83+
Svelte will warn you if you get it wrong.
6684

67-
Context is not inherently reactive. If you need reactive values in context then you can pass a `$state` object into context, whose properties _will_ be reactive.
85+
## Type-safe context
6886

69-
```svelte
70-
<!--- file: Parent.svelte --->
71-
<script>
72-
import { setContext } from 'svelte';
87+
A useful pattern is to wrap the calls to `setContext` and `getContext` inside helper functions that let you preserve type safety:
7388

74-
let value = $state({ count: 0 });
75-
setContext('counter', value);
76-
</script>
89+
```js
90+
/// file: context.js
91+
// @filename: ambient.d.ts
92+
interface User {}
7793

78-
<button onclick={() => value.count++}>increment</button>
79-
```
94+
// @filename: index.js
95+
// ---cut---
96+
import { getContext, setContext } from 'svelte';
8097

81-
```svelte
82-
<!--- file: Child.svelte --->
83-
<script>
84-
import { getContext } from 'svelte';
98+
let key = {};
8599

86-
const value = getContext('counter');
87-
</script>
100+
/** @param {User} user */
101+
export function setUserContext(user) {
102+
setContext(key, user);
103+
}
88104

89-
<p>Count is {value.count}</p>
105+
export function getUserContext() {
106+
return /** @type {User} */ (getContext(key));
107+
}
90108
```
91109

92-
To check whether a given `key` has been set in the context of a parent component, use `hasContext`.
110+
## Replacing global state
93111

94-
```svelte
95-
<script>
96-
import { hasContext } from 'svelte';
112+
When you have state shared by many different components, you might be tempted to put it in its own module and just import it wherever it's needed:
97113

98-
if (hasContext('key')) {
99-
// do something
114+
```js
115+
/// file: state.svelte.js
116+
export const myGlobalState = $state({
117+
user: {
118+
// ...
100119
}
101-
</script>
120+
// ...
121+
});
102122
```
103123

104-
You can also retrieve the whole context map that belongs to the closest parent component using `getAllContexts`. This is useful, for example, if you programmatically create a component and want to pass the existing context to it.
124+
In many cases this is perfectly fine, but there is a risk: if you mutate the state during server-side rendering (which is discouraged, but entirely possible!)...
105125

106126
```svelte
127+
<!--- file: App.svelte ---->
107128
<script>
108-
import { getAllContexts } from 'svelte';
129+
import { myGlobalState } from 'svelte';
109130
110-
const contexts = getAllContexts();
131+
let { data } = $props();
132+
133+
if (data.user) {
134+
myGlobalState.user = data.user;
135+
}
111136
</script>
112137
```
113138

114-
## Encapsulating context interactions
115-
116-
The above methods are very unopinionated about how to use them. When your app grows in scale, it's worthwhile to encapsulate setting and getting the context into functions and properly type them.
117-
118-
```ts
119-
// @errors: 2304
120-
import { getContext, setContext } from 'svelte';
121-
122-
let userKey = Symbol('user');
123-
124-
export function setUserContext(user: User) {
125-
setContext(userKey, user);
126-
}
127-
128-
export function getUserContext(): User {
129-
return getContext(userKey) as User;
130-
}
131-
```
139+
...then the data may be accessible by the _next_ user. Context solves this problem because it is not shared between requests.

apps/svelte.dev/content/docs/svelte/07-misc/07-v5-migration-guide.md

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ You don't have to migrate to the new syntax right away - Svelte 5 still supports
1111

1212
At the heart of Svelte 5 is the new runes API. Runes are basically compiler instructions that inform Svelte about reactivity. Syntactically, runes are functions starting with a dollar-sign.
1313

14-
### let -> $state
14+
### let $state
1515

1616
In Svelte 4, a `let` declaration at the top level of a component was implicitly reactive. In Svelte 5, things are more explicit: a variable is reactive when created using the `$state` rune. Let's migrate the counter to runes mode by wrapping the counter in `$state`:
1717

1818
```svelte
1919
<script>
20-
let count = +++$state(+++0+++)+++;
20+
let count = +++$state(0)+++;
2121
</script>
2222
```
2323

@@ -26,14 +26,14 @@ Nothing else changes. `count` is still the number itself, and you read and write
2626
> [!DETAILS] Why we did this
2727
> `let` being implicitly reactive at the top level worked great, but it meant that reactivity was constrained - a `let` declaration anywhere else was not reactive. This forced you to resort to using stores when refactoring code out of the top level of components for reuse. This meant you had to learn an entirely separate reactivity model, and the result often wasn't as nice to work with. Because reactivity is more explicit in Svelte 5, you can keep using the same API outside the top level of components. Head to [the tutorial](/tutorial) to learn more.
2828
29-
### $: -> $derived/$effect
29+
### $: $derived/$effect
3030

3131
In Svelte 4, a `$:` statement at the top level of a component could be used to declare a derivation, i.e. state that is entirely defined through a computation of other state. In Svelte 5, this is achieved using the `$derived` rune:
3232

3333
```svelte
3434
<script>
35-
let count = +++$state(+++0+++)+++;
36-
---$:--- +++const+++ double = +++$derived(+++count * 2+++)+++;
35+
let count = $state(0);
36+
---$:--- +++const+++ double = +++$derived(count * 2)+++;
3737
</script>
3838
```
3939

@@ -43,7 +43,8 @@ A `$:` statement could also be used to create side effects. In Svelte 5, this is
4343

4444
```svelte
4545
<script>
46-
let count = +++$state(+++0+++)+++;
46+
let count = $state(0);
47+
4748
---$:---+++$effect(() =>+++ {
4849
if (count > 5) {
4950
alert('Count is too high!');
@@ -74,14 +75,14 @@ Note that [when `$effect` runs is different]($effect#Understanding-dependencies)
7475
> - executing dependencies as needed and therefore being immune to ordering problems
7576
> - being TypeScript-friendly
7677
77-
### export let -> $props
78+
### export let $props
7879

7980
In Svelte 4, properties of a component were declared using `export let`. Each property was one declaration. In Svelte 5, all properties are declared through the `$props` rune, through destructuring:
8081

8182
```svelte
8283
<script>
83-
---export let optional = 'unset';
84-
export let required;---
84+
---export let optional = 'unset';---
85+
---export let required;---
8586
+++let { optional = 'unset', required } = $props();+++
8687
</script>
8788
```
@@ -106,8 +107,8 @@ In Svelte 5, the `$props` rune makes this straightforward without any additional
106107

107108
```svelte
108109
<script>
109-
---let klass = '';
110-
export { klass as class};---
110+
---let klass = '';---
111+
---export { klass as class};---
111112
+++let { class: klass, ...rest } = $props();+++
112113
</script>
113114
<button class={klass} {...---$$restProps---+++rest+++}>click me</button>
@@ -193,9 +194,9 @@ This function is deprecated in Svelte 5. Instead, components should accept _call
193194
```svelte
194195
<!--- file: Pump.svelte --->
195196
<script>
196-
---import { createEventDispatcher } from 'svelte';
197-
const dispatch = createEventDispatcher();
198-
---
197+
---import { createEventDispatcher } from 'svelte';---
198+
---const dispatch = createEventDispatcher();---
199+
199200
+++let { inflate, deflate } = $props();+++
200201
let power = $state(5);
201202
</script>
@@ -467,11 +468,11 @@ By now you should have a pretty good understanding of the before/after and how t
467468
We thought the same, which is why we provide a migration script to do most of the migration automatically. You can upgrade your project by using `npx sv migrate svelte-5`. This will do the following things:
468469

469470
- bump core dependencies in your `package.json`
470-
- migrate to runes (`let` -> `$state` etc)
471-
- migrate to event attributes for DOM elements (`on:click` -> `onclick`)
472-
- migrate slot creations to render tags (`<slot />` -> `{@render children()}`)
473-
- migrate slot usages to snippets (`<div slot="x">...</div>` -> `{#snippet x()}<div>...</div>{/snippet}`)
474-
- migrate obvious component creations (`new Component(...)` -> `mount(Component, ...)`)
471+
- migrate to runes (`let` `$state` etc)
472+
- migrate to event attributes for DOM elements (`on:click` `onclick`)
473+
- migrate slot creations to render tags (`<slot />` `{@render children()}`)
474+
- migrate slot usages to snippets (`<div slot="x">...</div>` `{#snippet x()}<div>...</div>{/snippet}`)
475+
- migrate obvious component creations (`new Component(...)` `mount(Component, ...)`)
475476

476477
You can also migrate a single component in VS Code through the `Migrate Component to Svelte 5 Syntax` command, or in our Playground through the `Migrate` button.
477478

0 commit comments

Comments
 (0)