You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: more details for errors/warnings on the site (#14632)
* docs: more details for errors/warnings on the site
Related to #11305
* Apply suggestions from code review
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix in correct place
* tab not spaces
* tweaks
* fix
* Apply suggestions from code review
* regenerate
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Copy file name to clipboardexpand all lines: documentation/docs/98-reference/.generated/client-warnings.md
+84
Original file line number
Diff line number
Diff line change
@@ -66,6 +66,31 @@ The easiest way to log a value as it changes over time is to use the [`$inspect`
66
66
The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value
67
67
```
68
68
69
+
Certain attributes like `src` on an `<img>` element will not be repaired during hydration, i.e. the server value will be kept. That's because updating these attributes can cause the image to be refetched (orinthecaseofan`<iframe>`, fortheframetobereloaded), even if they resolve to the same resource.
70
+
71
+
To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:
72
+
73
+
```svelte
74
+
<script>
75
+
let { src } =$props();
76
+
77
+
if (typeofwindow!=='undefined') {
78
+
// stash the value...
79
+
constinitial= src;
80
+
81
+
// unset it...
82
+
src =undefined;
83
+
84
+
$effect(() => {
85
+
// ...and reset after we've mounted
86
+
src = initial;
87
+
});
88
+
}
89
+
</script>
90
+
91
+
<img {src} />
92
+
```
93
+
69
94
### hydration_html_changed
70
95
71
96
```
@@ -76,6 +101,31 @@ The value of an `{@html ...}` block changed between server and client renders. T
76
101
The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value
77
102
```
78
103
104
+
If the `{@html ...}` value changes between the server and the client, it will not be repaired during hydration, i.e. the server value will be kept. That's because change detection during hydration is expensive and usually unnecessary.
105
+
106
+
To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:
107
+
108
+
```svelte
109
+
<script>
110
+
let { markup } =$props();
111
+
112
+
if (typeofwindow!=='undefined') {
113
+
// stash the value...
114
+
constinitial= markup;
115
+
116
+
// unset it...
117
+
markup =undefined;
118
+
119
+
$effect(() => {
120
+
// ...and reset after we've mounted
121
+
markup = initial;
122
+
});
123
+
}
124
+
</script>
125
+
126
+
{@html markup}
127
+
```
128
+
79
129
### hydration_mismatch
80
130
81
131
```
@@ -86,6 +136,10 @@ Hydration failed because the initial UI does not match what was rendered on the
86
136
Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
87
137
```
88
138
139
+
This warning is thrown when Svelte encounters an error while hydrating the HTML from the server. During hydration, Svelte walks the DOM, expecting a certain structure. If that structure is different (for example because the HTML was repaired by the DOM because of invalid HTML), then Svelte will run into issues, resulting in this warning.
140
+
141
+
During development, this error is often preceeded by a `console.error` detailing the offending HTML, which needs fixing.
142
+
89
143
### invalid_raw_snippet_render
90
144
91
145
```
@@ -110,6 +164,10 @@ Tried to unmount a component that was not mounted
110
164
%parent% passed a value to %child% with `bind:`, but the value is owned by %owner%. Consider creating a binding between %owner% and %parent%
111
165
```
112
166
167
+
Consider three components `GrandParent`, `Parent` and `Child`. If you do `<GrandParent bind:value>`, inside `GrandParent` pass on the variable via `<Parent {value} />` (notethemissing`bind:`) and then do `<Child bind:value>` inside `Parent`, this warning is thrown.
168
+
169
+
To fix it, `bind:` to the value instead of just passing a property (i.e. in this example do `<Parent bind:value />`).
170
+
113
171
### ownership_invalid_mutation
114
172
115
173
```
@@ -120,6 +178,32 @@ Mutating a value outside the component that created it is strongly discouraged.
120
178
%component% mutated a value owned by %owner%. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead
121
179
```
122
180
181
+
Consider the following code:
182
+
183
+
```svelte
184
+
<!--- file: App.svelte --->
185
+
<script>
186
+
import Child from './Child.svelte';
187
+
let person = $state({ name:'Florida', surname:'Man' });
188
+
</script>
189
+
190
+
<Child {person} />
191
+
```
192
+
193
+
```svelte
194
+
<!--- file:Child.svelte--->
195
+
<script>
196
+
let { person } =$props();
197
+
</script>
198
+
199
+
<input bind:value={person.name}>
200
+
<input bind:value={person.surname}>
201
+
```
202
+
203
+
`Child` is mutating `person` which is owned by `App` without being explicitly "allowed" to do so. This is strongly discouraged since it can create code that is hard to reason about at scale ("who mutated this value?"), hence the warning.
204
+
205
+
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
Copy file name to clipboardexpand all lines: documentation/docs/98-reference/.generated/compile-warnings.md
+117
Original file line number
Diff line number
Diff line change
@@ -610,6 +610,20 @@ Empty block
610
610
Unused CSS selector "%name%"
611
611
```
612
612
613
+
Svelte traverses both the template and the `<style>` tag to find out which of the CSS selectors are not used within the template, so it can remove them.
614
+
615
+
In some situations a selector may target an element that is not 'visible' to the compiler, for example because it is part of an `{@html ...}` tag or you're overriding styles in a child component. In these cases, use [`:global`](/docs/svelte/global-styles) to preserve the selector as-is:
616
+
617
+
```svelte
618
+
<div class="post">{@html content}</div>
619
+
620
+
<style>
621
+
.post :global {
622
+
p {...}
623
+
}
624
+
</style>
625
+
```
626
+
613
627
### element_invalid_self_closing_tag
614
628
615
629
```
@@ -622,6 +636,8 @@ Self-closing HTML tags for non-void elements are ambiguous — use `<%name% ...>
622
636
Using `on:%name%` to listen to the %name% event is deprecated. Use the event attribute `on%name%` instead
623
637
```
624
638
639
+
See [the migration guide](v5-migration-guide#Event-changes) for more info.
640
+
625
641
### export_let_unused
626
642
627
643
```
@@ -640,6 +656,8 @@ Component has unused export property '%name%'. If it is for external reference o
640
656
Svelte 5 components are no longer classes. Instantiate them using `mount` or `hydrate` (imported from 'svelte') instead.
641
657
```
642
658
659
+
See the [migration guide](v5-migration-guide#Components-are-no-longer-classes) for more info.
660
+
643
661
### node_invalid_placement_ssr
644
662
645
663
```
@@ -660,6 +678,30 @@ This code will work when the component is rendered on the client (which is why t
660
678
`%name%` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updates
661
679
```
662
680
681
+
This warning is thrown when the compiler detects the following:
682
+
- a variable was declared without `$state` or `$state.raw`
683
+
- the variable is reassigned
684
+
- the variable is read in a reactive context
685
+
686
+
In this case, changing the value will not correctly trigger updates. Example:
687
+
688
+
```svelte
689
+
<script>
690
+
let reactive = $state('reactive');
691
+
let stale = 'stale';
692
+
</script>
693
+
694
+
<p>This value updates: {reactive}</p>
695
+
<p>This value does not update: {stale}</p>
696
+
697
+
<button onclick={() => {
698
+
stale = 'updated';
699
+
reactive = 'updated';
700
+
}}>update</button>
701
+
```
702
+
703
+
To fix this, wrap your variable declaration with `$state`.
704
+
663
705
### options_deprecated_accessors
664
706
665
707
```
@@ -732,6 +774,12 @@ Reassignments of module-level declarations will not cause reactive statements to
732
774
`context="module"` is deprecated, use the `module` attribute instead
733
775
```
734
776
777
+
```svelte
778
+
<script ---context="module"--- +++context+++>
779
+
let foo = 'bar';
780
+
</script>
781
+
```
782
+
735
783
### script_unknown_attribute
736
784
737
785
```
@@ -744,12 +792,79 @@ Unrecognized attribute — should be one of `generics`, `lang` or `module`. If t
744
792
Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead
745
793
```
746
794
795
+
See [the migration guide](v5-migration-guide#Snippets-instead-of-slots) for more info.
796
+
747
797
### state_referenced_locally
748
798
749
799
```
750
800
State referenced in its own scope will never update. Did you mean to reference it inside a closure?
751
801
```
752
802
803
+
This warning is thrown when the compiler detects the following:
804
+
- A reactive variable is declared
805
+
- the variable is reassigned
806
+
- the variable is referenced inside the same scope it is declared and it is a non-reactive context
807
+
808
+
In this case, the state reassignment will not be noticed by whatever you passed it to. For example, if you pass the state to a function, that function will not notice the updates:
809
+
810
+
```svelte
811
+
<!--- file: Parent.svelte --->
812
+
<script>
813
+
import { setContext } from 'svelte';
814
+
815
+
let count = $state(0);
816
+
817
+
// warning: state_referenced_locally
818
+
setContext('count', count);
819
+
</script>
820
+
821
+
<button onclick={() => count++}>
822
+
increment
823
+
</button>
824
+
```
825
+
826
+
```svelte
827
+
<!--- file: Child.svelte --->
828
+
<script>
829
+
import { getContext } from 'svelte';
830
+
831
+
const count = getContext('count');
832
+
</script>
833
+
834
+
<!-- This will never update -->
835
+
<p>The count is {count}</p>
836
+
```
837
+
838
+
To fix this, reference the variable such that it is lazily evaluated. For the above example, this can be achieved by wrapping `count` in a function:
839
+
840
+
```svelte
841
+
<!--- file: Parent.svelte --->
842
+
<script>
843
+
import { setContext } from 'svelte';
844
+
845
+
let count = $state(0);
846
+
setContext('count', +++() => count+++);
847
+
</script>
848
+
849
+
<button onclick={() => count++}>
850
+
increment
851
+
</button>
852
+
```
853
+
854
+
```svelte
855
+
<!--- file: Child.svelte --->
856
+
<script>
857
+
import { getContext } from 'svelte';
858
+
859
+
const count = getContext('count');
860
+
</script>
861
+
862
+
<!-- This will update -->
863
+
<p>The count is {+++count()+++}</p>
864
+
```
865
+
866
+
For more info, see [Passing state into functions]($state#Passing-state-into-functions).
867
+
753
868
### store_rune_conflict
754
869
755
870
```
@@ -805,6 +920,8 @@ A derived value may be used in other contexts:
805
920
`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) instead
806
921
```
807
922
923
+
See [the note in the docs](legacy-svelte-self) for more info.
Copy file name to clipboardexpand all lines: documentation/docs/98-reference/.generated/shared-errors.md
+42
Original file line number
Diff line number
Diff line change
@@ -6,12 +6,54 @@
6
6
Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead
7
7
```
8
8
9
+
This error would be thrown in a setup like this:
10
+
11
+
```svelte
12
+
<!--- file: Parent.svelte --->
13
+
<List {items} let:entry>
14
+
<span>{entry}</span>
15
+
</List>
16
+
```
17
+
18
+
```svelte
19
+
<!--- file: List.svelte --->
20
+
<script>
21
+
let { items, children } = $props();
22
+
</script>
23
+
24
+
<ul>
25
+
{#each items as item}
26
+
<li>{@render children(item)}</li>
27
+
{/each}
28
+
</ul>
29
+
```
30
+
31
+
Here, `List.svelte` is using `{@render children(item)` which means it expects `Parent.svelte` to use snippets. Instead, `Parent.svelte` uses the deprecated `let:` directive. This combination of APIs is incompatible, hence the error.
32
+
9
33
### lifecycle_outside_component
10
34
11
35
```
12
36
`%name%(...)` can only be used during component initialisation
13
37
```
14
38
39
+
Certain lifecycle methods can only be used during component initialisation. To fix this, make sure you're invoking the method inside the _top level of the instance script_ of your component.
Copy file name to clipboardexpand all lines: documentation/docs/98-reference/.generated/shared-warnings.md
+9
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,8 @@
6
6
`<svelte:element this="%tag%">` is a void element — it cannot have content
7
7
```
8
8
9
+
Elements such as `<input>` cannot have content, any children passed to these elements will be ignored.
10
+
9
11
### state_snapshot_uncloneable
10
12
11
13
```
@@ -17,3 +19,10 @@ The following properties cannot be cloned with `$state.snapshot` — the return
17
19
18
20
%properties%
19
21
```
22
+
23
+
`$state.snapshot` tries to clone the given value in order to return a reference that no longer changes. Certain objects may not be cloneable, in which case the original value is returned. In the following example, `property` is cloned, but `window` is not, because DOM elements are uncloneable:
24
+
25
+
```js
26
+
conststate=$state({ property:'this is cloneable', window })
0 commit comments