Skip to content

Commit 7c540a3

Browse files
docs: legacy docs (sveltejs#493)
* docs: legacy docs * sync --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 6bbbed6 commit 7c540a3

19 files changed

+813
-3
lines changed

apps/svelte.dev/content/docs/svelte/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.

apps/svelte.dev/content/docs/svelte/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

apps/svelte.dev/content/docs/svelte/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.

apps/svelte.dev/content/docs/svelte/03-template-syntax/01-basic-markup.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag
1818
</div>
1919
```
2020

21-
## Attributes and props
21+
## Element attributes
2222

2323
By default, attributes work exactly like their HTML counterparts.
2424

@@ -72,6 +72,8 @@ When the attribute name and value match (`name={name}`), they can be replaced wi
7272
-->
7373
```
7474
75+
## Component props
76+
7577
By convention, values passed to components are referred to as _properties_ or _props_ rather than _attributes_, which are a feature of the DOM.
7678

7779
As with elements, `name={name}` can be replaced with the `{name}` shorthand.

apps/svelte.dev/content/docs/svelte/07-misc/04-custom-elements.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ document.body.innerHTML = `
3636
`;
3737
```
3838

39-
Any [props](basic-markup#Attributes-and-props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).
39+
Any [props](basic-markup#Component-props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).
4040

4141
```js
4242
// @noErrors

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ The `render` function passed to `createRawSnippet` should return HTML for a sing
5959
### legacy_recursive_reactive_block
6060

6161
```
62-
Detected a migrated `$:` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
62+
Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
6363
```
6464

6565
### lifecycle_double_unmount
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: Overview
3+
---
4+
5+
Svelte 5 introduced some significant changes to Svelte's API, including [runes](what-are-runes), [snippets](snippet) and event attributes. As a result, some Svelte 3/4 features are deprecated (though supported for now, unless otherwise specified) and will eventually be removed. We recommend that you incrementally [migrate your existing code](v5-migration-guide).
6+
7+
The following pages document these features for
8+
9+
- people still using Svelte 3/4
10+
- people using Svelte 5, but with components that haven't yet been migrated
11+
12+
Since Svelte 3/4 syntax still works in Svelte 5, we will distinguish between _legacy mode_ and _runes mode_. Once a component is in runes mode (which you can opt into by using runes, or by explicitly setting the `runes: true` compiler option), legacy mode features are no longer available.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Reactive let/var declarations
3+
---
4+
5+
In runes mode, reactive state is explicitly declared with the [`$state` rune]($state).
6+
7+
In legacy mode, variables declared at the top level of a component are automatically considered _reactive_. Reassigning or mutating these variables (`count += 1` or `object.x = y`) will cause the UI to update.
8+
9+
```svelte
10+
<script>
11+
let count = 0;
12+
</script>
13+
14+
<button on:click={() => count += 1}>
15+
clicks: {count}
16+
</button>
17+
```
18+
19+
Because Svelte's legacy mode reactivity is based on _assignments_, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to 'tell' the compiler to update the UI:
20+
21+
```svelte
22+
<script>
23+
let numbers = [1, 2, 3, 4];
24+
25+
function addNumber() {
26+
// this method call does not trigger an update
27+
numbers.push(numbers.length + 1);
28+
29+
// this assignment will update anything
30+
// that depends on `numbers`
31+
numbers = numbers;
32+
}
33+
</script>
34+
```
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: Reactive $: statements
3+
---
4+
5+
In runes mode, reactions to state updates are handled with the [`$derived`]($derived) and [`$effect`]($effect) runes.
6+
7+
In legacy mode, any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with a `$:` [label](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). These statements run after other code in the `<script>` and before the component markup is rendered, then whenever the values that they depend on change.
8+
9+
```svelte
10+
<script>
11+
let a = 1;
12+
let b = 2;
13+
14+
// this is a 'reactive statement', and it will re-run
15+
// when `a`, `b` or `sum` change
16+
$: console.log(`${a} + ${b} = ${sum}`);
17+
18+
// this is a 'reactive assignment' — `sum` will be
19+
// recalculated when `a` or `b` change. It is
20+
// not necessary to declare `sum` separately
21+
$: sum = a + b;
22+
</script>
23+
```
24+
25+
Statements are ordered _topologically_ by their dependencies and their assignments: since the `console.log` statement depends on `sum`, `sum` is calculated first even though it appears later in the source.
26+
27+
Multiple statements can be combined by putting them in a block:
28+
29+
```js
30+
// @noErrors
31+
$: {
32+
// recalculate `total` when `items` changes
33+
total = 0;
34+
35+
for (const item of items) {
36+
total += item.value;
37+
}
38+
}
39+
```
40+
41+
The left-hand side of a reactive assignments can be an identifier, or it can be a destructuring assignment:
42+
43+
```js
44+
// @noErrors
45+
$: ({ larry, moe, curly } = stooges);
46+
```
47+
48+
## Understanding dependencies
49+
50+
The dependencies of a `$:` statement are determined at compile time — they are whichever variables are referenced (but not assigned to) inside the statement.
51+
52+
In other words, a statement like this will _not_ re-run when `count` changes, because the compiler cannot 'see' the dependency:
53+
54+
```js
55+
// @noErrors
56+
let count = 0;
57+
let double = () => count * 2;
58+
59+
$: doubled = double();
60+
```
61+
62+
Similarly, topological ordering will fail if dependencies are referenced indirectly: `z` will never update, because `y` is not considered 'dirty' when the update occurs. Moving `$: z = y` below `$: setY(x)` will fix it:
63+
64+
```svelte
65+
<script>
66+
let x = 0;
67+
let y = 0;
68+
69+
$: z = y;
70+
$: setY(x);
71+
72+
function setY(value) {
73+
y = value;
74+
}
75+
</script>
76+
```
77+
78+
## Browser-only code
79+
80+
Reactive statements run during server-side rendering as well as in the browser. This means that any code that should only run in the browser must be wrapped in an `if` block:
81+
82+
```js
83+
// @noErrors
84+
$: if (browser) {
85+
document.title = title;
86+
}
87+
```
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: export let
3+
---
4+
5+
In runes mode, [component props](basic-markup#Component-props) are declared with the [`$props`]($props) rune, allowing parent components to pass in data.
6+
7+
In legacy mode, props are marked with the `export` keyword, and can have a default value:
8+
9+
```svelte
10+
<script>
11+
export let foo;
12+
export let bar = 'default value';
13+
14+
// Values that are passed in as props
15+
// are immediately available
16+
console.log({ foo });
17+
</script>
18+
```
19+
20+
The default value is used if it would otherwise be `undefined` when the component is created.
21+
22+
> [!NOTE] Unlike in runes mode, if the parent component changes a prop from a defined value to `undefined`, it does not revert to the initial value.
23+
24+
Props without default values are considered _required_, and Svelte will print a warning during development if no value is provided, which you can squelch by specifying `undefined` as the default value:
25+
26+
```js
27+
export let foo +++= undefined;+++
28+
```
29+
30+
## Component exports
31+
32+
An exported `const`, `class` or `function` declaration is _not_ considered a prop — instead, it becomes part of the component's API:
33+
34+
```svelte
35+
<!--- file: Greeter.svelte--->
36+
<script>
37+
export function greet(name) {
38+
alert(`hello ${name}!`);
39+
}
40+
</script>
41+
```
42+
43+
```svelte
44+
<!--- file: App.svelte --->
45+
<script>
46+
import Greeter from './Greeter.svelte';
47+
48+
let greeter;
49+
</script>
50+
51+
<Greeter bind:this={greeter} />
52+
53+
<button on:click={() => greeter.greet('world')}>
54+
greet
55+
</button>
56+
```
57+
58+
## Renaming props
59+
60+
The `export` keyword can appear separately from the declaration. This is useful for renaming props, for example in the case of a reserved word:
61+
62+
```svelte
63+
<!--- file: App.svelte --->
64+
<script>
65+
/** @type {string} */
66+
let className;
67+
68+
// creates a `class` property, even
69+
// though it is a reserved word
70+
export { className as class };
71+
</script>
72+
```

0 commit comments

Comments
 (0)