Skip to content

Commit 8f9bd83

Browse files
Sync svelte docs (#1891)
sync svelte docs Co-authored-by: svelte-docs-bot[bot] <196124396+svelte-docs-bot[bot]@users.noreply.github.com>
1 parent d138f34 commit 8f9bd83

8 files changed

Lines changed: 235 additions & 25 deletions

File tree

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

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ You can use `$effect` anywhere, not just at the top level of a component, as lon
4242

4343
> [!NOTE] Svelte uses effects internally to represent logic and expressions in your template — this is how `<h1>hello {name}!</h1>` updates when `name` changes.
4444
45-
An effect can return a _teardown function_ which will run immediately before the effect re-runs ([demo](/playground/untitled#H4sIAAAAAAAAE42SQVODMBCF_8pOxkPRKq3HCsx49K4n64xpskjGkDDJ0tph-O8uINo6HjxB3u7HvrehE07WKDbiyZEhi1osRWksRrF57gQdm6E2CKx_dd43zU3co6VB28mIf-nKO0JH_BmRRRVMQ8XWbXkAgfKtI8jhIpIkXKySu7lSG2tNRGZ1_GlYr1ZTD3ddYFmiosUigbyAbpC2lKbwWJkIB8ZhhxBQBWRSw6FCh3sM8GrYTthL-wqqku4N44TyqEgwF3lmRHr4Op0PGXoH31c5rO8mqV-eOZ49bikgtcHBL55tmhIkEMqg_cFB2TpFxjtg703we6NRL8HQFCS07oSUCZi6Rm04lz1yytIHBKoQpo1w6Gsm4gmyS8b8Y5PydeMdX8gwS2Ok4I-ov5NZtvQde95GMsccn_1wzNKfu3RZtS66cSl9lvL7qO1aIk7knbJGvefdtIOzi73M4bYvovUHDFk6AcX_0HRESxnpBOW_jfCDxIZCi_1L_wm4xGQ60wIAAA==)).
45+
An effect can return a _teardown function_ which will run immediately before the effect re-runs:
4646

47+
<!-- codeblock:start {"title":"Effect teardown"} -->
4748
```svelte
49+
<!--- file: App.svelte --->
4850
<script>
4951
let count = $state(0);
5052
let milliseconds = $state(1000);
@@ -69,6 +71,7 @@ An effect can return a _teardown function_ which will run immediately before the
6971
<button onclick={() => (milliseconds *= 2)}>slower</button>
7072
<button onclick={() => (milliseconds /= 2)}>faster</button>
7173
```
74+
<!-- codeblock:end -->
7275

7376
Teardown functions also run when the effect is destroyed, which happens when its parent is destroyed (for example, a component is unmounted) or the parent effect re-runs.
7477

@@ -207,9 +210,11 @@ Apart from the timing, `$effect.pre` works exactly like `$effect`.
207210

208211
## `$effect.tracking`
209212

210-
The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template ([demo](/playground/untitled#H4sIAAAAAAAACn3PwYrCMBDG8VeZDYIt2PYeY8Dn2HrIhqkU08nQjItS-u6buAt7UDzmz8ePyaKGMWBS-nNRcmdU-hHUTpGbyuvI3KZvDFLal0v4qvtIgiSZUSb5eWSxPfWSc4oB2xDP1XYk8HHiSHkICeXKeruDDQ4Demlldv4y0rmq6z10HQwuJMxGVv4mVVXDwcJS0jP9u3knynwtoKz1vifT_Z9Jhm0WBCcOTlDD8kyspmML5qNpHg40jc3fFryJ0iWsp_UHgz3180oBAAA=)):
213+
The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template:
211214

215+
<!-- codeblock:start {"title":"$effect.tracking()"} -->
212216
```svelte
217+
<!--- file: App.svelte --->
213218
<script>
214219
console.log('in component setup:', $effect.tracking()); // false
215220
@@ -220,14 +225,27 @@ The `$effect.tracking` rune is an advanced feature that tells you whether or not
220225
221226
<p>in template: {$effect.tracking()}</p> <!-- true -->
222227
```
228+
<!-- codeblock:end -->
223229

224230
It is used to implement abstractions like [`createSubscriber`](/docs/svelte/svelte-reactivity#createSubscriber), which will create listeners to update reactive values but _only_ if those values are being tracked (rather than, for example, read inside an event handler).
225231

226232
## `$effect.pending`
227233

228-
When using [`await`](await-expressions) in components, the `$effect.pending()` rune tells you how many promises are pending in the current [boundary](svelte-boundary), not including child boundaries ([demo](/playground/untitled#H4sIAAAAAAAAE3WRMU_DMBCF_8rJdHDUqilILGkaiY2RgY0yOPYZWbiOFV8IleX_jpMUEAIWS_7u-d27c2ROnJBV7B6t7WDsequAozKEqmAbpo3FwKqnyOjsJ90EMr-8uvN-G97Q0sRaEfAvLjtH6CjbsDrI3nhqju5IFgkEHGAVSBDy62L_SdtvejPTzEU4Owl6cJJM50AoxcUG2gLiVM31URgChyM89N3JBORcF3BoICA9mhN2A3G9gdvdrij2UJYgejLaSCMsKLTivNj0SEOf7WEN7ZwnHV1dfqd2dTsQ5QCdk9bI10PkcxexXqcmH3W51Jt_le2kbH8os9Y3UaTcNLYpDx-Xab6GTHXpZ128MhpWqDVK2np0yrgXXqQpaLa4APDLBkIF8bd2sYql0Sn_DeE7sYr6AdNzvgljR-MUq7SwAdMHeUtgHR4CAAA=)):
234+
When using [`await`](await-expressions) in components, the `$effect.pending()` rune tells you how many promises are pending in the current [boundary](svelte-boundary), not including child boundaries:
229235

236+
<!-- codeblock:start {"title":"$effect.pending"} -->
230237
```svelte
238+
<!--- file: App.svelte --->
239+
<script>
240+
let a = $state(1);
241+
let b = $state(2);
242+
243+
async function add(a, b) {
244+
await new Promise((f) => setTimeout(f, 500)); // artificial delay
245+
return a + b;
246+
}
247+
</script>
248+
231249
<button onclick={() => a++}>a++</button>
232250
<button onclick={() => b++}>b++</button>
233251
@@ -237,6 +255,7 @@ When using [`await`](await-expressions) in components, the `$effect.pending()` r
237255
<p>pending promises: {$effect.pending()}</p>
238256
{/if}
239257
```
258+
<!-- codeblock:end -->
240259

241260
## `$effect.root`
242261

@@ -286,9 +305,11 @@ In general, `$effect` is best considered something of an escape hatch — useful
286305
287306
If you're using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that [deriveds can be directly overridden]($derived#Overriding-derived-values) as of Svelte 5.25.
288307

289-
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/playground/untitled#H4sIAAAAAAAAE5WRTWrDMBCFryKGLBJoY3fRjWIHeoiu6i6UZBwEY0VE49TB-O6VxrFTSih0qe_Ne_OjHpxpEDS8O7ZMeIAnqC1hAP3RA1990hKI_Fb55v06XJA4sZ0J-IjvT47RcYyBIuzP1vO2chVHHFjxiQ2pUr3k-SZRQlbBx_LIFoEN4zJfzQph_UMQr4hRXmBd456Xy5Uqt6pPKHmkfmzyPAZL2PCnbRpg8qWYu63I7lu4gswOSRYqrPNt3CgeqqzgbNwRK1A76w76YqjFspfcQTWmK3vJHlQm1puSTVSeqdOc_r9GaeCHfUSY26TXry6Br4RSK3C6yMEGT-aqVU3YbUZ2NF6rfP2KzXgbuYzY46czdgyazy0On_FlLH3F-UDXhgIO35UGlA1rAgAA)):
308+
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Instead of using effects for this...
290309

310+
<!-- codeblock:start {"title":"Setting state in effects (don't do this!)"} -->
291311
```svelte
312+
<!--- file: App.svelte --->
292313
<script>
293314
const total = 100;
294315
let spent = $state(0);
@@ -312,11 +333,21 @@ You might be tempted to do something convoluted with effects to link one value t
312333
<input type="range" bind:value={left} max={total} />
313334
{left}/{total} left
314335
</label>
336+
337+
<style>
338+
label {
339+
display: flex;
340+
gap: 0.5em;
341+
}
342+
</style>
315343
```
344+
<!-- codeblock:end -->
316345

317-
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE5VRvW7CMBB-FcvqECQK6dDFJEgsnfoGTQdDLsjSxVjxhYKivHvPBwFUsXS8774_nwftbQva6I_e78gdvNo6Xzu_j3quG4cQtfkaNJ1DIiWA8atkE8IiHgEpYVsb4Rm-O3gCT2yji7jrXKB15StiOJKiA1lUpXrL81VCEUjFwHTGXiJZgiyf3TYIjSxq6NwR6uyifr0ohMbEZnpHH2rWf7ImS8KZGtK6osl_UqelRIyVL5b3ir5AuwWUtoXzoee6fIWy0p31e6i0XMocLfZQDuI6qtaeykGcR7UU6XWznFAZU9LN_X9B2UyVayk9f3ji0-REugen6U9upDOCcAWcLlS7GNCejWoQTqsLtrfBqHzxDu3DrUTOf0xwIm2o62H85sk6_OHG2jQWI4y_3byXXGMCAAA=)):
346+
...use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible:
318347

348+
<!-- codeblock:start {"title":"Setting state with function bindings"} -->
319349
```svelte
350+
<!--- file: App.svelte --->
320351
<script>
321352
const total = 100;
322353
let spent = $state(0);
@@ -336,6 +367,14 @@ Instead, use `oninput` callbacks or — better still — [function bindings](bin
336367
<input type="range" +++bind:value={() => left, updateLeft}+++ max={total} />
337368
{left}/{total} left
338369
</label>
370+
371+
<style>
372+
label {
373+
display: flex;
374+
gap: 0.5em;
375+
}
376+
</style>
339377
```
378+
<!-- codeblock:end -->
340379

341380
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/02-runes/05-$props.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ let { a, b, c, ...others } = $props();
6565

6666
## Updating props
6767

68-
References to a prop inside a component update when the prop itself updates — when `count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the child component is able to temporarily override the prop value, which can be useful for unsaved ephemeral state ([demo](/playground/untitled#H4sIAAAAAAAAE6WQ0WrDMAxFf0WIQR0Wmu3VTQJln7HsIfVcZubIxlbGRvC_DzuBraN92qPula50tODZWB1RPi_IX16jLALWSOOUq6P3-_ihLWftNEZ9TVeOWBNHlNhGFYznfqCBzeRdYHh6M_YVzsFNsNs3pdpGd4eBcqPVDMrNxNDBXeSRtXioDgO1zU8ataeZ2RE4Utao924RFXQ9iHXwvoPHKpW1xY4g_Bg0cSVhKS0p560Za95612ZC02ONrD8ZJYdZp_rGQ37ff_mSP86Np2TWZaNNmdcH56P4P67K66_SXoK9pG-5dF5Z9QEAAA==)):
68+
References to a prop inside a component update when the prop itself updates — when `count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the child component is able to temporarily override the prop value, which can be useful for unsaved ephemeral state:
6969

70+
<!-- codeblock:start {"title":"Temporarily updating props","selected":"Child.svelte"} -->
7071
```svelte
7172
<!--- file: App.svelte --->
7273
<script>
@@ -92,11 +93,13 @@ References to a prop inside a component update when the prop itself updates —
9293
clicks (child): {count}
9394
</button>
9495
```
96+
<!-- codeblock:end -->
9597

9698
While you can temporarily _reassign_ props, you should not _mutate_ props unless they are [bindable]($bindable).
9799

98-
If the prop is a regular object, the mutation will have no effect ([demo](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2W1QmorQgJXk0RC3PkBwiExG9WQrC17U4Es_ztKUkQp9OjxzM7bjcjtSKjwyfKNp1aLORA4b13ADHszUED1HFE-3eyaBcy-Mw_O5eFAg8xa1wb6T9eWhVgCKiyD9sZJ3XAjZnTWCzzuzfAKvbcjbPJieR2jm_uGy-InweXqtd0baaliBG0nFgW3kBIUNWYo9CGoxE-UsgvIpw2_oc9-LmAPJBCPDJCggqvlVtvdH9puErEMlvVg9HsVtzuoaojzkKKAfRuALVDfk5ZZW0fmy05wXcFdwyktlUs-KIinljTXrRVnm7-kL9dYLVbUAQAA)):
100+
If the prop is a regular object, the mutation will have no effect:
99101

102+
<!-- codeblock:start {"title":"Non-reactive props","selected":"Child.svelte"} -->
100103
```svelte
101104
<!--- file: App.svelte --->
102105
<script>
@@ -119,9 +122,11 @@ If the prop is a regular object, the mutation will have no effect ([demo](/playg
119122
clicks: {object.count}
120123
</button>
121124
```
125+
<!-- codeblock:end -->
122126

123-
If the prop is a reactive state proxy, however, then mutations _will_ have an effect but you will see an [`ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation) warning, because the component is mutating state that does not 'belong' to it ([demo](/playground/untitled#H4sIAAAAAAAAE3WR0U7DMAxFf8VESBuiauG1WycheOEbKA9p67FA6kSNszJV-XeUZhMw2GN8r-1znUmQ7FGU4pn2UqsOes-SlSGRia3S6ET5Mgk-2OiJBZGdOh6szd0eNcdaIx3-V28NMRI7UYq1awdleVNTzaq3ZmB43CndwXYwPSzyYn4dWxermqJRI4Np3rFlqODasWRcTtAaT1zCHYSbVU3r4nsyrdPMKTUFKDYiE4yfLEoePIbsQpqfy3_nOVMuJIqg0wk1RFg7GOuWfwEbz2wIDLVatR_VtLyBagNTHFIUMCqtoZXeIfAOU1JoUJsR2IC3nWTMjt7GM4yKdyBhlAMpesvhydCC0y_i0ZagHByMh26WzUhXUUxKnpbcVnBfUwhznJnNlac7JkuIURL-2VVfwxflyrWcSQIAAA==)):
127+
If the prop is a reactive state proxy, however, then mutations _will_ have an effect but you will see an [`ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation) warning, because the component is mutating state that does not 'belong' to it:
124128

129+
<!-- codeblock:start {"title":"Invalid mutation","selected":"Child.svelte"} -->
125130
```svelte
126131
<!--- file: App.svelte --->
127132
<script>
@@ -148,8 +153,19 @@ If the prop is a reactive state proxy, however, then mutations _will_ have an ef
148153
clicks: {object.count}
149154
</button>
150155
```
156+
<!-- codeblock:end -->
151157

152-
The fallback value of a prop not declared with `$bindable` is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates ([demo](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2VkIbUVoYFraCIh7vwA4eC4G9Wta1vxpgJZ_nfkBEQp9OjxzOzTRGHlkUQlXpy9G0gq1idCL43ppDrAD84HUYheGwqieo2CP3y2Z0EU3-En79fhRIaz1slA_-nKWSbLQVRiE9SgPTetbVkfvRsYzztttugHd8RiXU6vr-jisbWb8idhN7O3bEQhmN5ZVDyMlIorcOddv_Eufq4AGmJEuG5PilEjQrnRcoV7JCTUuJlGWq7-YHYjs7NwVhmtDnVcrlA3iLmzLLGTAdaB-j736h68Oxv-JM1I0AFjoG1OzPfX023c1nhobUoT39QeKsRzS8owM8DFTG_pE6dcVl70AQAA))
158+
The fallback value of a prop not declared with `$bindable` is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates:
159+
160+
<!-- codeblock:start {"title":"Non-reactive fallback props","selected":"Child.svelte"} -->
161+
```svelte
162+
<!--- file: App.svelte --->
163+
<script>
164+
import Child from './Child.svelte';
165+
</script>
166+
167+
<Child />
168+
```
153169

154170
```svelte
155171
<!--- file: Child.svelte --->
@@ -164,6 +180,7 @@ The fallback value of a prop not declared with `$bindable` is left untouched —
164180
clicks: {object.count}
165181
</button>
166182
```
183+
<!-- codeblock:end -->
167184

168185
In summary: don't mutate props. Either use callback props to communicate changes, or — if parent and child should share the same object — use the [`$bindable`]($bindable) rune.
169186

apps/svelte.dev/content/docs/svelte/02-runes/07-$inspect.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ tags: rune-inspect
66

77
> [!NOTE] `$inspect` only works during development. In a production build it becomes a noop.
88
9-
The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object or array using fine-grained reactivity will cause it to re-fire ([demo](/playground/untitled#H4sIAAAAAAAACkWQ0YqDQAxFfyUMhSotdZ-tCvu431AXtGOqQ2NmmMm0LOK_r7Utfby5JzeXTOpiCIPKT5PidkSVq2_n1F7Jn3uIcEMSXHSw0evHpAjaGydVzbUQCmgbWaCETZBWMPlKj29nxBDaHj_edkAiu12JhdkYDg61JGvE_s2nR8gyuBuiJZuDJTyQ7eE-IEOzog1YD80Lb0APLfdYc5F9qnFxjiKWwbImo6_llKRQVs-2u91c_bD2OCJLkT3JZasw7KLA2XCX31qKWE6vIzNk1fKE0XbmYrBTufiI8-_8D2cUWBA_AQAA)):
9+
The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object or array using fine-grained reactivity will cause it to re-fire:
1010

11+
<!-- codeblock:start {"title":"$inspect(...)"} -->
1112
```svelte
13+
<!--- file: App.svelte --->
1214
<script>
1315
let count = $state(0);
1416
let message = $state('hello');
@@ -19,14 +21,17 @@ The `$inspect` rune is roughly equivalent to `console.log`, with the exception t
1921
<button onclick={() => count++}>Increment</button>
2022
<input bind:value={message} />
2123
```
24+
<!-- codeblock:end -->
2225

2326
On updates, a stack trace will be printed, making it easy to find the origin of a state change (unless you're in the playground, due to technical limitations).
2427

2528
## $inspect(...).with
2629

27-
`$inspect` returns a property `with`, which you can invoke with a callback, which will then be invoked instead of `console.log`. The first argument to the callback is either `"init"` or `"update"`; subsequent arguments are the values passed to `$inspect` ([demo](/playground/untitled#H4sIAAAAAAAACkVQ24qDMBD9lSEUqlTqPlsj7ON-w7pQG8c2VCchmVSK-O-bKMs-DefKYRYx6BG9qL4XQd2EohKf1opC8Nsm4F84MkbsTXAqMbVXTltuWmp5RAZlAjFIOHjuGLOP_BKVqB00eYuKs82Qn2fNjyxLtcWeyUE2sCRry3qATQIpJRyD7WPVMf9TW-7xFu53dBcoSzAOrsqQNyOe2XUKr0Xi5kcMvdDB2wSYO-I9vKazplV1-T-d6ltgNgSG1KjVUy7ZtmdbdjqtzRcphxMS1-XubOITJtPrQWMvKnYB15_1F7KKadA_AQAA)):
30+
`$inspect(...)` returns an object with a `with` method, which you can invoke with a callback that will then be invoked instead of `console.log`. The first argument to the callback is either `"init"` or `"update"`; subsequent arguments are the values passed to `$inspect`:
2831

32+
<!-- codeblock:start {"title":"$inspect(...).with(...)"} -->
2933
```svelte
34+
<!--- file: App.svelte --->
3035
<script>
3136
let count = $state(0);
3237
@@ -39,6 +44,7 @@ On updates, a stack trace will be printed, making it easy to find the origin of
3944
4045
<button onclick={() => count++}>Increment</button>
4146
```
47+
<!-- codeblock:end -->
4248

4349
## $inspect.trace(...)
4450

apps/svelte.dev/content/docs/svelte/03-template-syntax/03-each.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,34 @@ You can freely use destructuring and rest patterns in each blocks.
9090
{#each expression, index}...{/each}
9191
```
9292

93-
In case you just want to render something `n` times, you can omit the `as` part ([demo](/playground/untitled#H4sIAAAAAAAAE3WR0W7CMAxFf8XKNAk0WsSeUEaRpn3Guoc0MbQiJFHiMlDVf18SOrZJ48259_jaVgZmxBEZZ28thgCNFV6xBdt1GgPj7wOji0t2EqI-wa_OleGEmpLWiID_6dIaQkMxhm1UdwKpRQhVzWSaVORJNdvWpqbhAYVsYQCNZk8thzWMC_DCHMZk3wPSThNQ088I3mghD9UwSwHwlLE5PMIzVFUFq3G7WUZ2OyUvU3JOuZU332wCXTRmtPy1NgzXZtUFp8WFw9536uWqpbIgPEaDsJBW90cTOHh0KGi2XsBq5-cT6-3nPauxXqHnsHJnCFZ3CvJVkyuCQ0mFF9TZyCQ162WGvteLKfG197Y3iv_pz_fmS68Hxt8iPBPj5HscP8YvCNX7uhYCAAA=)):
93+
In case you just want to render something `n` times, you can omit the `as` part:
9494

95+
<!-- codeblock:start {"title":"Chess board"} -->
9596
```svelte
97+
<!--- file: App.svelte --->
9698
<div class="chess-board">
9799
{#each { length: 8 }, rank}
98100
{#each { length: 8 }, file}
99101
<div class:black={(rank + file) % 2 === 1}></div>
100102
{/each}
101103
{/each}
102104
</div>
105+
106+
<style>
107+
.chess-board {
108+
display: grid;
109+
grid-template-columns: repeat(8, 1fr);
110+
rows: repeat(8, 1fr);
111+
border: 1px solid black;
112+
aspect-ratio: 1;
113+
114+
.black {
115+
background: black;
116+
}
117+
}
118+
</style>
103119
```
120+
<!-- codeblock:end -->
104121

105122
## Else blocks
106123

0 commit comments

Comments
 (0)