Skip to content

Commit d68fd16

Browse files
committed
docs: legacy docs
add docs on old syntax
1 parent a6e416d commit d68fd16

17 files changed

+811
-0
lines changed

documentation/docs/01-introduction/03-svelte-files.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ A `<script>` tag with a `module` attribute runs once when the module first evalu
5050

5151
You can `export` bindings from this block, and they will become exports of the compiled module. You cannot `export default`, since the default export is the component itself.
5252

53+
> [!LEGACY]
54+
> In Svelte 4, this script tag was created using `<script context="module">`
55+
5356
## `<style>`
5457

5558
CSS inside a `<style>` block will be scoped to that component.

documentation/docs/01-introduction/04-svelte-js-files.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ title: .svelte.js and .svelte.ts files
55
Besides `.svelte` files, Svelte also operates on `.svelte.js` and `.svelte.ts` files.
66

77
These behave like any other `.js` or `.ts` module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app.
8+
9+
> [!LEGACY]
10+
> This is a concept that didn't exist prior to Svelte 5

documentation/docs/02-runes/01-what-are-runes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ They differ from normal JavaScript functions in important ways, however:
1919
- You don't need to import them — they are part of the language
2020
- They're not values — you can't assign them to a variable or pass them as arguments to a function
2121
- Just like JavaScript keywords, they are only valid in certain positions (the compiler will help you if you put them in the wrong place)
22+
23+
> [!LEGACY]
24+
> Runes didn't exist prior to Svelte 5.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Overview
3+
---
4+
5+
Svelte 5 came with some significant changes to Svelte's API. These include runes, snippets and event attributes. As a result some of the API known from Svelte 3 and 4 is deprecated and will be removed at some point in the future. It is advised to incrementally migrate towards the new syntax, see the [migration guide](v5-migration-guide) for more info.
6+
7+
That said, this legacy syntax is still available today and can be used side by side with the new syntax. The following pages contain reference documentation of said syntax.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: let is reactive
3+
---
4+
5+
To change component state and trigger a re-render, just assign to a locally declared variable.
6+
7+
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect.
8+
9+
```svelte
10+
<script>
11+
let count = 0;
12+
13+
function handleClick() {
14+
// calling this function will trigger an
15+
// update if the markup references `count`
16+
count = count + 1;
17+
}
18+
</script>
19+
```
20+
21+
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to trigger the update. This and more details can also be found in the [tutorial](https://learn.svelte.dev/tutorial/updating-arrays-and-objects).
22+
23+
```svelte
24+
<script>
25+
let arr = [0, 1];
26+
27+
function handleClick() {
28+
// this method call does not trigger an update
29+
arr.push(2);
30+
// this assignment will trigger an update
31+
// if the markup references `arr`
32+
arr = arr;
33+
}
34+
</script>
35+
```
36+
37+
Svelte's `<script>` blocks are run only when the component is created, so assignments within a `<script>` block are not automatically run again when a prop updates. If you'd like to track changes to a prop, see the next example in the following section.
38+
39+
```svelte
40+
<script>
41+
export let person;
42+
// this will only set `name` on component creation
43+
// it will not update when `person` does
44+
let { name } = person;
45+
</script>
46+
```
47+
48+
> [!NOTE]
49+
> In Svelte 5+, state is explicitly reactive via the [`$state` rune]($state)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: $:
3+
---
4+
5+
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` [JS label syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). Reactive statements run after other script code and before the component markup is rendered, whenever the values that they depend on have changed.
6+
7+
```svelte
8+
<script>
9+
export let title;
10+
export let person;
11+
12+
// this will update `document.title` whenever
13+
// the `title` prop changes
14+
$: document.title = title;
15+
16+
$: {
17+
console.log(`multiple statements can be combined`);
18+
console.log(`the current title is ${title}`);
19+
}
20+
21+
// this will update `name` when 'person' changes
22+
$: ({ name } = person);
23+
24+
// don't do this. it will run before the previous line
25+
let name2 = name;
26+
</script>
27+
```
28+
29+
Only values which directly appear within the `$:` block will become dependencies of the reactive statement. For example, in the code below `total` will only update when `x` changes, but not `y`.
30+
31+
```svelte
32+
<!--- file: App.svelte --->
33+
<script>
34+
let x = 0;
35+
let y = 0;
36+
37+
/** @param {number} value */
38+
function yPlusAValue(value) {
39+
return value + y;
40+
}
41+
42+
$: total = yPlusAValue(x);
43+
</script>
44+
45+
Total: {total}
46+
<button on:click={() => x++}> Increment X </button>
47+
48+
<button on:click={() => y++}> Increment Y </button>
49+
```
50+
51+
It is important to note that the reactive blocks are ordered via simple static analysis at compile time, and all the compiler looks at are the variables that are assigned to and used within the block itself, not in any functions called by them. This means that `yDependent` will not be updated when `x` is updated in the following example:
52+
53+
```svelte
54+
<!--- file: App.svelte --->
55+
<script>
56+
let x = 0;
57+
let y = 0;
58+
59+
/** @param {number} value */
60+
function setY(value) {
61+
y = value;
62+
}
63+
64+
$: yDependent = y;
65+
$: setY(x);
66+
</script>
67+
```
68+
69+
Moving the line `$: yDependent = y` below `$: setY(x)` will cause `yDependent` to be updated when `x` is updated.
70+
71+
If a statement consists entirely of an assignment to an undeclared variable, Svelte will inject a `let` declaration on your behalf.
72+
73+
```svelte
74+
<!--- file: App.svelte --->
75+
<script>
76+
/** @type {number} */
77+
export let num;
78+
79+
// we don't need to declare `squared` and `cubed`
80+
// — Svelte does it for us
81+
$: squared = num * num;
82+
$: cubed = squared * num;
83+
</script>
84+
```
85+
86+
> [!NOTE]
87+
> In Svelte 5+, reactions are handled via the [`$derived`]($derived) and [`$effect`]($effect) runes
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: export let
3+
---
4+
5+
Svelte uses the `export` keyword to mark a variable declaration as a _property_ or _prop_, which means it becomes accessible to consumers of the component (see the section on [attributes and props](/docs/basic-markup#attributes-and-props) for more information).
6+
7+
```svelte
8+
<script>
9+
export let foo;
10+
11+
// Values that are passed in as props
12+
// are immediately available
13+
console.log({ foo });
14+
</script>
15+
```
16+
17+
You can specify a default initial value for a prop. It will be used if the component's consumer doesn't specify the prop on the component (or if its initial value is `undefined`) when instantiating the component. Note that if the values of props are subsequently updated, then any prop whose value is not specified will be set to `undefined` (rather than its initial value).
18+
19+
In development mode (see the [compiler options](/docs/svelte-compiler#compile)), a warning will be printed if no default initial value is provided and the consumer does not specify a value. To squelch this warning, ensure that a default initial value is specified, even if it is `undefined`.
20+
21+
```svelte
22+
<script>
23+
export let bar = 'optional default initial value';
24+
export let baz = undefined;
25+
</script>
26+
```
27+
28+
If you export a `const`, `class` or `function`, it is readonly from outside the component. Functions are valid prop values, however, as shown below.
29+
30+
```svelte
31+
<!--- file: App.svelte --->
32+
<script>
33+
// these are readonly
34+
export const thisIs = 'readonly';
35+
36+
/** @param {string} name */
37+
export function greet(name) {
38+
alert(`hello ${name}!`);
39+
}
40+
41+
// this is a prop
42+
export let format = (n) => n.toFixed(2);
43+
</script>
44+
```
45+
46+
Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](/docs/component-directives#bind-this).
47+
48+
You can use reserved words as prop names.
49+
50+
```svelte
51+
<!--- file: App.svelte --->
52+
<script>
53+
/** @type {string} */
54+
let className;
55+
56+
// creates a `class` property, even
57+
// though it is a reserved word
58+
export { className as class };
59+
</script>
60+
```
61+
62+
> [!NOTE]
63+
> In Svelte 5+, use the [`$props`]($props) rune instead
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: $$props
3+
---
4+
5+
`$$props` references all props that are passed to a component, including ones that are not declared with `export`. Using `$$props` will not perform as well as references to a specific prop because changes to any prop will cause Svelte to recheck all usages of `$$props`. But it can be useful in some cases – for example, when you don't know at compile time what props might be passed to a component.
6+
7+
```svelte
8+
<Widget {...$$props} />
9+
```
10+
11+
> [!NOTE]
12+
> In Svelte 5+, this concept is unnecessary as you can use [`let prop = $props()`]($props) instead
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: $$restProps
3+
---
4+
5+
`$$restProps` contains only the props which are _not_ declared with `export`. It can be used to pass down other unknown attributes to an element in a component. It shares the same performance characteristics compared to specific property access as `$$props`.
6+
7+
```svelte
8+
<input {...$$restProps} />
9+
```
10+
11+
> [!NOTE]
12+
> In Svelte 5+, this concept is unnecessary as you can use [`let { foo, ...rest } = $props()`]($props) instead
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: on:
3+
---
4+
5+
```svelte
6+
<!--- copy: false --->
7+
on:eventname={handler}
8+
```
9+
10+
```svelte
11+
<!--- copy: false --->
12+
on:eventname|modifiers={handler}
13+
```
14+
15+
Use the `on:` directive to listen to DOM events.
16+
17+
```svelte
18+
<!--- file: App.svelte --->
19+
<script>
20+
let count = 0;
21+
22+
/** @param {MouseEvent} event */
23+
function handleClick(event) {
24+
count += 1;
25+
}
26+
</script>
27+
28+
<button on:click={handleClick}>
29+
count: {count}
30+
</button>
31+
```
32+
33+
Handlers can be declared inline with no performance penalty. As with attributes, directive values may be quoted for the sake of syntax highlighters.
34+
35+
```svelte
36+
<button on:click={() => (count += 1)}>
37+
count: {count}
38+
</button>
39+
```
40+
41+
Add _modifiers_ to DOM events with the `|` character.
42+
43+
```svelte
44+
<form on:submit|preventDefault={handleSubmit}>
45+
<!-- the `submit` event's default is prevented,
46+
so the page won't reload -->
47+
</form>
48+
```
49+
50+
The following modifiers are available:
51+
52+
- `preventDefault` — calls `event.preventDefault()` before running the handler
53+
- `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
54+
- `stopImmediatePropagation` - calls `event.stopImmediatePropagation()`, preventing other listeners of the same event from being fired.
55+
- `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
56+
- `nonpassive` — explicitly set `passive: false`
57+
- `capture` — fires the handler during the _capture_ phase instead of the _bubbling_ phase
58+
- `once` — remove the handler after the first time it runs
59+
- `self` — only trigger handler if `event.target` is the element itself
60+
- `trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.
61+
62+
Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
63+
64+
If the `on:` directive is used without a value, the component will _forward_ the event, meaning that a consumer of the component can listen for it.
65+
66+
```svelte
67+
<button on:click> The component itself will emit the click event </button>
68+
```
69+
70+
It's possible to have multiple event listeners for the same event:
71+
72+
```svelte
73+
<!--- file: App.svelte --->
74+
<script>
75+
let counter = 0;
76+
function increment() {
77+
counter = counter + 1;
78+
}
79+
80+
/** @param {MouseEvent} event */
81+
function track(event) {
82+
trackEvent(event);
83+
}
84+
</script>
85+
86+
<button on:click={increment} on:click={track}>Click me!</button>
87+
```
88+
89+
> [!NOTE]
90+
> In Svelte 5+, use event attributes instead
91+
> ```svelte
92+
> <button onclick={() => alert('clicked')}>click me</button>
93+
> ```
94+
95+
## Component events
96+
97+
Component events created with [`createEventDispatcher`](svelte#createEventDispatcher) create a `CustomEvent`. These events do not bubble. The detail argument corresponds to the `CustomEvent.detail` property and can contain any type of data.
98+
99+
```svelte
100+
<script>
101+
import { createEventDispatcher } from 'svelte';
102+
103+
const dispatch = createEventDispatcher();
104+
</script>
105+
106+
<button on:click={() => dispatch('notify', 'detail value')}>Fire Event</button>
107+
```
108+
109+
Events dispatched from child components can be listened to in their parent. Any data provided when the event was dispatched is available on the `detail` property of the event object.
110+
111+
```svelte
112+
<script>
113+
function callbackFunction(event) {
114+
console.log(`Notify fired! Detail: ${event.detail}`);
115+
}
116+
</script>
117+
118+
<Child on:notify={callbackFunction} />
119+
```
120+
121+
> [!NOTE]
122+
> If you're planning on migrating to Svelte 5, use callback props instead. This will make upgrading easier as `createEventDispatcher` is deprecated
123+
> ```svelte
124+
> <script>
125+
> export let notify;
126+
> </script>
127+
>
128+
> <button on:click={() => notify('detail value')}>Fire Event</button>
129+
> ```

0 commit comments

Comments
 (0)