Skip to content

Commit 1a15144

Browse files
authored
Merge branch 'main' into generated-banner
2 parents 7b9a201 + d6a64f8 commit 1a15144

File tree

26 files changed

+951
-240
lines changed

26 files changed

+951
-240
lines changed

apps/svelte.dev/content/blog/2024-12-01-advent-of-svelte.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,17 @@ You can now do `bind:value={get, set}` to validate and transform bound values. T
7171
- [docs](/docs/svelte/bind#Function-bindings)
7272
- [demo](/playground/1ddd82f573b94201b3c8fcab33bf0a46?version=5.9.0)
7373

74-
## Day 9
74+
## Day 9: error and warning documentation
7575

76-
Coming soon!
76+
When Svelte emits a warning or error (whether at build time, when the compiler is running, or when the app is running on the server or in the browser) it will now be accompanied by a link to the corresponding entry in the documentation containing a description (which is omitted from production builds, to save bytes) and — in some cases, with more to come — more details on why it happened and what you can do to fix it.
7777

78-
## Day 10
78+
- [demo](/playground/8095884c1f5040ea846669b904083e25?version=5.10.0)
7979

80-
Coming soon!
80+
## Day 10: SvelteKit `init` hooks
81+
82+
A lot of you wanted a place to put asynchronous setup work that happens before your SvelteKit app starts up. You can now export an `init` function from `hooks.server.js` and `hooks.client.js` that will be awaited before any other stuff happens.
83+
84+
- [docs](https://svelte.dev/docs/kit/hooks#Shared-hooks-init)
8185

8286
## Day 11
8387

apps/svelte.dev/content/docs/kit/30-advanced/20-hooks.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,25 @@ During development, if an error occurs because of a syntax error in your Svelte
238238

239239
> [!NOTE] Make sure that `handleError` _never_ throws an error
240240
241+
### init
242+
243+
This function runs once, when the server is created or the app starts in the browser, and is a useful place to do asynchronous work such as initializing a database connection.
244+
245+
> [!NOTE] If your environment supports top-level await, the `init` function is really no different from writing your initialisation logic at the top level of the module, but some environments — most notably, Safari — don't.
246+
247+
```js
248+
/// file: src/hooks.server.js
249+
import * as db from '$lib/server/database';
250+
251+
/** @type {import('@sveltejs/kit').ServerInit} */
252+
export async function init() {
253+
await db.connect();
254+
}
255+
```
256+
257+
> [!NOTE]
258+
> In the browser, asynchronous work in `init` will delay hydration, so be mindful of what you put in there.
259+
241260
## Universal hooks
242261

243262
The following can be added to `src/hooks.js`. Universal hooks run on both server and client (not to be confused with shared hooks, which are environment-specific).

apps/svelte.dev/content/docs/kit/98-reference/[email protected]

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,24 @@ Compress files in `directory` with gzip and brotli, where appropriate. Generates
854854
</div>
855855
</div></div>
856856

857+
## ClientInit
858+
859+
<blockquote class="since note">
860+
861+
Available since 2.10.0
862+
863+
</blockquote>
864+
865+
The [`init`](/docs/kit/hooks#Shared-hooks-init) will be invoked once the app starts in the browser
866+
867+
<div class="ts-block">
868+
869+
```dts
870+
type ClientInit = () => MaybePromise<void>;
871+
```
872+
873+
</div>
874+
857875
## Config
858876

859877
See the [configuration reference](/docs/kit/configuration) for details.
@@ -2350,6 +2368,24 @@ A `[file]: size` map of all assets imported by server code
23502368
</div>
23512369
</div></div>
23522370

2371+
## ServerInit
2372+
2373+
<blockquote class="since note">
2374+
2375+
Available since 2.10.0
2376+
2377+
</blockquote>
2378+
2379+
The [`init`](/docs/kit/hooks#Shared-hooks-init) will be invoked before the server responds to its first request
2380+
2381+
<div class="ts-block">
2382+
2383+
```dts
2384+
type ServerInit = () => MaybePromise<void>;
2385+
```
2386+
2387+
</div>
2388+
23532389
## ServerInitOptions
23542390

23552391
<div class="ts-block">

apps/svelte.dev/content/docs/kit/98-reference/20-$app-navigation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function afterNavigate(
4444

4545
## beforeNavigate
4646

47-
A navigation interceptor that triggers before we navigate to a new URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls.
47+
A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls.
4848

4949
Calling `cancel()` will prevent the navigation from completing. If `navigation.type === 'leave'` — meaning the user is navigating away from the app (or closing the tab) — calling `cancel` will trigger the native browser unload confirmation dialog. In this case, the navigation may or may not be cancelled depending on the user's response.
5050

apps/svelte.dev/content/docs/svelte/98-reference/.generated/client-warnings.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,31 @@ The easiest way to log a value as it changes over time is to use the [`$inspect`
6666
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
6767
```
6868

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 (or in the case of an `<iframe>`, for the frame to be reloaded), 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 (typeof window !== 'undefined') {
78+
// stash the value...
79+
const initial = 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+
6994
### hydration_html_changed
7095
7196
```
@@ -76,6 +101,31 @@ The value of an `{@html ...}` block changed between server and client renders. T
76101
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
77102
```
78103
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 (typeof window !== 'undefined') {
113+
// stash the value...
114+
const initial = 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+
79129
### hydration_mismatch
80130
81131
```
@@ -86,6 +136,10 @@ Hydration failed because the initial UI does not match what was rendered on the
86136
Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
87137
```
88138
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+
89143
### invalid_raw_snippet_render
90144
91145
```
@@ -110,6 +164,10 @@ Tried to unmount a component that was not mounted
110164
%parent% passed a value to %child% with `bind:`, but the value is owned by %owner%. Consider creating a binding between %owner% and %parent%
111165
```
112166

167+
Consider three components `GrandParent`, `Parent` and `Child`. If you do `<GrandParent bind:value>`, inside `GrandParent` pass on the variable via `<Parent {value} />` (note the missing `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+
113171
### ownership_invalid_mutation
114172

115173
```
@@ -120,6 +178,32 @@ Mutating a value outside the component that created it is strongly discouraged.
120178
%component% mutated a value owned by %owner%. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead
121179
```
122180

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).
206+
123207
### reactive_declaration_non_reactive_property
124208
125209
```

apps/svelte.dev/content/docs/svelte/98-reference/.generated/compile-warnings.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,20 @@ Empty block
610610
Unused CSS selector "%name%"
611611
```
612612

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+
613627
### element_invalid_self_closing_tag
614628

615629
```
@@ -622,6 +636,8 @@ Self-closing HTML tags for non-void elements are ambiguous — use `<%name% ...>
622636
Using `on:%name%` to listen to the %name% event is deprecated. Use the event attribute `on%name%` instead
623637
```
624638

639+
See [the migration guide](v5-migration-guide#Event-changes) for more info.
640+
625641
### export_let_unused
626642

627643
```
@@ -640,6 +656,8 @@ Component has unused export property '%name%'. If it is for external reference o
640656
Svelte 5 components are no longer classes. Instantiate them using `mount` or `hydrate` (imported from 'svelte') instead.
641657
```
642658

659+
See the [migration guide](v5-migration-guide#Components-are-no-longer-classes) for more info.
660+
643661
### node_invalid_placement_ssr
644662

645663
```
@@ -660,6 +678,30 @@ This code will work when the component is rendered on the client (which is why t
660678
`%name%` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updates
661679
```
662680

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+
663705
### options_deprecated_accessors
664706

665707
```
@@ -732,6 +774,12 @@ Reassignments of module-level declarations will not cause reactive statements to
732774
`context="module"` is deprecated, use the `module` attribute instead
733775
```
734776

777+
```svelte
778+
<script ---context="module"--- +++context+++>
779+
let foo = 'bar';
780+
</script>
781+
```
782+
735783
### script_unknown_attribute
736784

737785
```
@@ -744,12 +792,79 @@ Unrecognized attribute — should be one of `generics`, `lang` or `module`. If t
744792
Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead
745793
```
746794

795+
See [the migration guide](v5-migration-guide#Snippets-instead-of-slots) for more info.
796+
747797
### state_referenced_locally
748798

749799
```
750800
State referenced in its own scope will never update. Did you mean to reference it inside a closure?
751801
```
752802

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+
753868
### store_rune_conflict
754869

755870
```
@@ -805,6 +920,8 @@ A derived value may be used in other contexts:
805920
`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) instead
806921
```
807922

923+
See [the note in the docs](legacy-svelte-self) for more info.
924+
808925
### unknown_code
809926

810927
```

0 commit comments

Comments
 (0)