This is the full developer documentation for Svelte and SvelteKit. # Start of Svelte documentation # Aperçu Svelte est un framework permettant de construire des interfaces sur le web. Il utilise un compilateur pour transformer les composants écrits en HTML, CSS et JavaScript... ```svelte ``` ... en du code JavaScript léger et optimisé. Vous pouvez vous en servir pour construire ce que vous voulez sur le web, depuis des composants isolés jusqu'à des applications full-stack ambitieuses (en utilisant le framework d'application compagnon de Svelte, [SvelteKit](../kit)) et tout ce que vous pouvez imaginer entre les deux. Ces pages servent de documentation de référence. Si vous débutez avec Svelte, nous vous recommandons de commencer par le [tutoriel interactif](/tutorial) et de revenir ici lorsque vous aurez des questions. Vous pouvez aussi essayer Svelte directement dans le [bac à sable](/playground) ou sur [StackBlitz](https://sveltekit.new), s'il vous faut un environnement plus complet. # Débuter avec Svelte Nous recommandons d'utiliser [SvelteKit](../kit), le framework d'application officiel développé par l'équipe Svelte, qui se base sur [Vite](https://vite.dev) : ```bash npx sv create myapp cd myapp npm install npm run dev ``` Ne vous inquiétez pas si vous ne connaissez pas encore Svelte ! Vous pouvez dans un premier temps ignorer toutes les choses merveilleuses que SvelteKit apporte et vous y intéresser plus tard. ## Alternatives à SvelteKit [!VO]Alternatives to SvelteKit Vous pouvez aussi utiliser Svelte directement avec Vite en exécutant `npm create vite@latest` et en choisissant l'option `svelte`. De cette manière, `npm run build` va générer des fichiers HTML, JS et CSS dans le dossier `dist` grâce à [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte). Dans la plupart des cas vous aurez également certainement besoin de choisir une [librairie de routing](faq#Is-there-a-router). Il existe également des plugins pour [Rollup](https://github.com/sveltejs/rollup-plugin-svelte), [Webpack](https://github.com/sveltejs/svelte-loader) [et quelques autres](https://sveltesociety.dev/packages?category=build-plugins), mais nous recommandons l'utilisation de Vite. ## Outillage des éditeurs [!VO]Editor tooling L'équipe de Svelte maintient une [extension VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), et des intégrations sont également disponibles pour d'autres [éditeurs](https://sveltesociety.dev/resources#editor-support) et outils. Vous pouvez aussi vérifier la qualité de votre code dans votre terminal en utilisant [sv check](https://github.com/sveltejs/cli). ## Obtenir de l'aide [!VO]Getting help N'ayez pas peur de demander de l'aide dans le forum de discussion de notre serveur [Discord](/chat) ! Vous pourrez aussi trouver des réponses sur [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte). # Fichiers .svelte Les composants sont les briques de base des application Svelte. Ils sont écrits dans des fichiers `.svelte`, en utilisant une version augmentée de HTML. Les trois sections — script, styles, et markup — sont optionnelles. ```svelte /// file: MyComponent.svelte ``` ## ` ``` Vous pouvez `export`er des liaisons depuis ce bloc, elles deviendront des exports du module copmilé. Vous ne pouvez pas utiliser `export default`, puisque l'export par défaut est le composant lui-même. > [!NOTE] Si vous utilisez TypeScript et importez dans un fichier `ts` de tels exports depuis un > bloc `module`, assurez-vous que votre éditeur soit configuré correctement pour permettre à > TypeScript d'avoir conscience de ces exports. C'est le cas avec notre extension VSCode et avec le > plugin IntelliJ, mais dans d'autres cas vous aurez peut-être besoin de configurer notre [plugin > d'éditeur dédié à TypeScript](https://www.npmjs.com/package/typescript-svelte-plugin). > [!LEGACY] > Avec Svelte 4, cette balise script se définit en utilisant ` ``` You can specify a fallback value for a prop. It will be used if the component's consumer doesn't specify the prop on the component when instantiating the component, or if the passed value is `undefined` at some point. ```svelte ``` To get all properties, use rest syntax: ```svelte ``` You can use reserved words as prop names. ```svelte ``` If you're using TypeScript, you can declare the prop types: ```svelte ``` If you're using JavaScript, you can declare the prop types using JSDoc: ```svelte ``` If you export a `const`, `class` or `function`, it is readonly from outside the component. ```svelte ``` Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](bindings#bind:this). ### Reactive variables To change component state and trigger a re-render, just assign to a locally declared variable that was declared using the `$state` rune. Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect. ```svelte ``` Svelte's ` ``` If you'd like to react to changes to a prop, use the `$derived` or `$effect` runes instead. ```svelte ``` For more information on reactivity, read the documentation around runes. # Reactivity fundamentals Reactivity is at the heart of interactive UIs. When you click a button, you expect some kind of response. It's your job as a developer to make this happen. It's Svelte's job to make your job as intuitive as possible, by providing a good API to express reactive systems. ## Runes Svelte 5 uses _runes_, a powerful set of primitives for controlling reactivity inside your Svelte components and inside `.svelte.js` and `.svelte.ts` modules. Runes are function-like symbols that provide instructions to the Svelte compiler. You don't need to import them from anywhere — when you use Svelte, they're part of the language. The following sections introduce the most important runes for declare state, derived state and side effects at a high level. For more details refer to the later sections on [state](state) and [side effects](side-effects). ## `$state` Reactive state is declared with the `$state` rune: ```svelte ``` You can also use `$state` in class fields (whether public or private): ```js // @errors: 7006 2554 class Todo { done = $state(false); text = $state(); constructor(text) { this.text = text; } } ``` > [!LEGACY] > In Svelte 4, state was implicitly reactive if the variable was declared at the top level > > ```svelte > > > > ``` ## `$derived` Derived state is declared with the `$derived` rune: ```svelte

{count} doubled is {doubled}

``` The expression inside `$derived(...)` should be free of side-effects. Svelte will disallow state changes (e.g. `count++`) inside derived expressions. As with `$state`, you can mark class fields as `$derived`. > [!LEGACY] > In Svelte 4, you could use reactive statements for this. > > ```svelte > > > > >

{count} doubled is {doubled}

> ``` > > This only worked at the top level of a component. ## `$effect` To run _side-effects_ when the component is mounted to the DOM, and when values change, we can use the `$effect` rune ([demo](/playground/untitled#H4sIAAAAAAAAE31T24rbMBD9lUG7kAQ2sbdlX7xOYNk_aB_rQhRpbAsU2UiTW0P-vbrYubSlYGzmzMzROTPymdVKo2PFjzMzfIusYB99z14YnfoQuD1qQh-7bmdFQEonrOppVZmKNBI49QthCc-OOOH0LZ-9jxnR6c7eUpOnuv6KeT5JFdcqbvbcBcgDz1jXKGg6ncFyBedYR6IzLrAZwiN5vtSxaJA-EzadfJEjKw11C6GR22-BLH8B_wxdByWpvUYtqqal2XB6RVkG1CoHB6U1WJzbnYFDiwb3aGEdDa3Bm1oH12sQLTcNPp7r56m_00mHocSG97_zd7ICUXonA5fwKbPbkE2ZtMJGGVkEdctzQi4QzSwr9prnFYNk5hpmqVuqPQjNnfOJoMF22lUsrq_UfIN6lfSVyvQ7grB3X2mjMZYO3XO9w-U5iLx42qg29md3BP_ni5P4gy9ikTBlHxjLzAtPDlyYZmRdjAbGq7HprEQ7p64v4LU_guu0kvAkhBim3nMplWl8FreQD-CW20aZR0wq12t-KqDWeBywhvexKC3memmDwlHAv9q4Vo2ZK8KtK0CgX7u9J8wXbzdKv-nRnfF_2baTqlYoWUF2h5efl9-n0O6koAMAAA==)): ```svelte ``` The function passed to `$effect` will run when the component mounts, and will re-run after any changes to the values it reads that were declared with `$state` or `$derived` (including those passed in with `$props`). Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied. > [!LEGACY] > In Svelte 4, you could use reactive statements for this. > > ```svelte > > > > ``` > > This only worked at the top level of a component. # C’est quoi une rune ? > [!NOTE] **rune** /ro͞on/ _nom_ > > Une lettre ou caractère graphique utilisé comme symbole magique ou mystique. Les runes sont les symboles utilisés dans les fichiers `.svelte` et `.svelte.js`/`.svelte.ts` pour contrôler le compilateur Svelte. Si vous pensez Svelte comme un langage, les runes font partie de sa syntaxe — elles sont des _mots-clés_. Les runes ont un préfixe `$` et ressemblent à des fonctions : ```js let message = $state('coucou'); ``` Néanmoins, elles diffèrent des fonctions JavaScript habituelles de manière importante : - Vous n'avez pas besoin de les importer — elles font partie du langage - Elles ne représentent pas de valeurs — vous ne pouvez pas les assigner à une variable ou les passer comme argument à une fonction - Comme pour les mots-clés JavaScript, elles ne sont valides que dans certaines positions (le compilateur vous préviendra si vous les utilisez au mauvais endroit) > [!LEGACY] > Les runes n'existaient pas avant Svelte 5. # $state La rune `$state` vous permet de créer un _état réactif_, ce qui signifie que votre UI _réagit_ lorsque cet état évolue. ```svelte ``` À la différence d'autres frameworks que vous avez peut-être croisés, il n'y a pas d'API pour interagir avec un état — `count` est juste un nombre, et non un objet ou une fonction, et vous pouvez le mettre à jour comme vous mettriez à jour n'importe quelle variable. ### L'état profond [!VO]Deep state Si `$state` est utilisé avec un tableau ou un objet simple, le résultat est un _proxy d'état_ profondément réactif. Les [Proxys](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Proxy) permettent à Svelte d'exécuter du code lors de la lecture ou de l'écriture de propriétés, en particulier via des méthodes comme `array.push(...)`, déclenchant des mises à jour granulaires. > [!NOTE] Les classes comme `Set` et `Map` ne seront pas transformées en Proxy, mais Svelte fournit > des implémentations réactives pour plusieurs built-ins similaires que vous pouvez importer depuis > [`svelte/reactivity`](./svelte-reactivity). L'état est transformé en Proxy de manière récursive jusqu'à ce que Svelte trouve autre chose qu'un tableau ou un objet simple. Dans un cas comme celui-là... ```js let todos = $state([ { done: false, text: 'ajouter plus de todos' } ]); ``` ... modifier une propriété d'un élément individuel du tableau va déclencher des mises à jour pour tous les éléments de votre UI qui dépendent spécifiquement de cette propriété : ```js let todos = [{ done: false, text: 'add more todos' }]; // ---cut--- todos[0].done = !todos[0].done; ``` Si vous ajoutez un nouvel objet à ce tableau via `.push`, celui-ci sera également transformé en Proxy : ```js let todos = [{ done: false, text: 'add more todos' }]; // ---cut--- todos.push({ done: false, text: 'déjeuner' }); ``` > [!NOTE] Lorsque vous mettez à jour les propriétés d'un Proxy, l'objet d'origine n'est _pas_ muté. Notez que si vous déstructurez une valeur réactive, les références ne sont pas réactives — comme pour du JavaScript classique, elles sont évaluées au moment de la déstructuration : ```js let todos = [{ done: false, text: 'ajouter plus de tâches' }]; // ---cut--- let { done, text } = todos[0]; // ceci n'affectera pas la valeur de `done` todos[0].done = !todos[0].done; ``` ### Classes Vous pouvez aussi utiliser `$state` avec les champs d'une classe (qu'ils soient publics ou privés) : ```js // @errors: 7006 2554 class Todo { done = $state(false); text = $state(); constructor(text) { this.text = text; } reset() { this.text = ''; this.done = false; } } ``` Lorsque vous appelez des méthodes en JavaScript, la valeur de [`this`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/this) a de l'importance. L'exemple suivant ne fonctionne pas, car la référence `this` dans la méthode `reset` est le ` ``` Vous pouvez soit utiliser une fonction inlinée... ```svelte ``` ... soit une fonction fléchée dans la définition de la classe : ```js // @errors: 7006 2554 class Todo { done = $state(false); text = $state(); constructor(text) { this.text = text; } +++reset = () => {+++ this.text = ''; this.done = false; } } ``` > [!NOTE] Le compilateur transforme `done` et `text` en méthodes `get`/`set` sur le prototype de > classe qui référencent des champs privés. Cela signifie que les propriétés ne sont pas > énumérables. ## `$state.raw` Si vous ne souhaitez pas que les objets et tableaux soient profondément réactifs, vous pouvez utiliser `$state.raw`. Un état déclaré avec `$state.raw` ne peut pas être muté ; il peut seulement être _réassigné_. En d'autres mots, plutôt que de réassigner une propriété ou un objet, ou d'utiliser une méthode de tableau comme `push`, remplacez entièrement l'objet ou le tableau si vous voulez le mettre à jour : ```js let person = $state.raw({ name: 'Heraclitus', age: 49 }); // ceci n'aura aucun effet person.age += 1; // ceci fonctionne, car nous créons une nouvelle personne person = { name: 'Heraclitus', age: 50 }; ``` Ceci peut améliorer la performance dans le cas de grands tableaux et objets que vous ne prévoyez de toutes façons pas de muter, puisqu'il n'y a pas le surcoût de les rendre profondément réactifs. Notez qu'un état `raw` peut _contenir_ des états réactifs (par exemple, un tableau `raw` d'objets réactifs). ## `$state.snapshot` Pour prendre un instantané statique d'un Proxy profondément réactif `$state`, utilisez `$state.snapshot` : ```svelte ``` Ceci est pratique lorsque vous souhaitez passer un état à une librairie externe ou à une API qui ne s'attend pas à recevoir un proxy, comme dans le cas de `structuredClone`. ## Passer de l'état à des fonctions [!VO]Passing state into functions JavaScript est un langage qui _passe par valeur_ — lorsque vous appelez une fonction, les arguments sont les _valeurs_ plutôt que les _variables_. En d'autres mots : ```js /// file: index.js // @filename: index.js // ---cut--- /** * @param {number} a * @param {number} b */ function add(a, b) { return a + b; } let a = 1; let b = 2; let total = add(a, b); console.log(total); // 3 a = 3; b = 4; console.log(total); // toujours 3! ``` Si `add` a besoin d'un accès aux valeurs _courantes_ de `a` et `b`, et de renvoyer la valeur `total` mise à jour, vous devez utiliser plutôt des fonctions : ```js /// file: index.js // @filename: index.js // ---cut--- /** * @param {() => number} getA * @param {() => number} getB */ function add(+++getA, getB+++) { return +++() => getA() + getB()+++; } let a = 1; let b = 2; let total = add+++(() => a, () => b)+++; console.log(+++total()+++); // 3 a = 3; b = 4; console.log(+++total()+++); // 7 ``` L'état dans Svelte fonctionne de la même façon — lorsque vous référencez quelque chose déclaré avec la rune `$state`... ```js let a = +++$state(1)+++; let b = +++$state(2)+++; ``` ... vous accédez à sa _valeur courante_. Notez que le terme "fonctions" est large — il englobe les propriétés des proxies et les propriétés [`get`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/get) et [`set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set)... ```js /// file: index.js // @filename: index.js // ---cut--- /** * @param {{ a: number, b: number }} input */ function add(input) { return { get value() { return input.a + input.b; } }; } let input = $state({ a: 1, b: 2 }); let total = add(input); console.log(total.value); // 3 input.a = 3; input.b = 4; console.log(total.value); // 7 ``` ... toutefois si vous vous retrouvez à écrire du code similaire, envisagez plutôt l'utilisation de [classes](#Classes). # $derived Vous pouvez déclarer un état dérivé avec la rune `$derived` : ```svelte

Le double de {count} vaut {doubled}

``` L'expression à l'intérieur de `$derived(...)` ne doit pas contenir d'effet de bord. Svelte empêchera les changements d'état (par ex. `count++`) à l'intérieur d'expressions dérivées. Comme avec `$state`, vous pouvez définir les champs d'une classe en utilisant `$derived`. > [!NOTE] Le code d'un composant Svelte est uniquement exécuté à sa création. Sans la rune > `$derived`, `doubled` maintiendrait sa valeur originale même si `count` change de valeur. ## `$derived.by` Parfois, certaines derivations complexes nécessitent plus qu'une simple expression. Dans ces cas là, vous pouvez utiliser `$derived.by`, qui prend une fonction comme argument. ```svelte ``` Par essence, `$derived(expression)` est équivalent à `$derived.by(() => expression)`. ## Comprendre les dépendences Tout ce qui est lu de manière synchrone au de l'expression de `$derived` (ou du corps de la fonction de `$derived.by`) est considérée comme une _dépendence_ de l'état dérivé. Lorsqu'un des états dont il dépend est mis à jour, l'état dérivé sera marqué comme _sale_ et recalculé la prochaine fois que sa valeur est lue. Pour exempter un morceau d'état d'être considéré comme une dépendance, utilisez [`untrack`](svelte#untrack). ## Propagation de la mise à jour [!VO]Update propagation Svelte utilise un concept appelée _réactivité push-pull_ — lorsque l'état est mis à jour, tout ce qui dépend de l'état (directement ou non) est immédiatement notifié du changement (le 'push'), mais les valeurs dérivées ne sont pas ré-évaluées tant qu'elles ne sont lues (le 'pull'). Si la nouvelle valeur d'un état dérivé est identique en termes de référence que la valeur précédente, les mises à jour en aval seront ignorées. Autrement dit, Svelte ne mettra à jour le texte au sein du bouton que lorsque `large` change, pas lorsque `count` change, même si `large` dépend de `count` : ```svelte ``` # $effect Les effets permettent à votre application de _faire des choses_. Lorsque Svelte exécute une fonction d'effet, il détermine les états (et d'états dérivés) qui sont lus, (à moins qu'ils ne soient exemptés par [`untrack`](svelte#untrack)), et ré-exécute la fonction lorsque ces états changent. La plupart des effets dans une application Svelte sont créés par Svelte lui-même — c'est ce qui permet de mettre à jour le texte dans `

coucou {name} !

` lorsque que `name` change, par exemple. Mais vous pouvez aussi créer vos propres effets avec la rune `$effect`, ce qui sert lorsque vous avez besoin de synchroniser un système extérieur (que ce soit une librairie, un élément ``, ou quelque chose sur le réseau) avec un état au sein de votre application Svelte. > [!NOTE] Évitez de trop vous servir d'`$effect` ! Lorsque trop de choses sont gérés via des effets, > le code devient difficile à comprendre et à maintenir. Voir la partie [quand ne pas utiliser > `$effect`](#When-not-to-use-$effect) pour en savoir plus sur les moyens de les éviter. Vos effets sont exécutés après le montage du composant dans le DOM, et lors d'une [micro-tâche](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) juste après la mise à jour de l'état ([démo](/playground/untitled#H4sIAAAAAAAAE31S246bMBD9lZF3pSRSAqTVvrCAVPUP2sdSKY4ZwJJjkD0hSVH-vbINuWxXfQH5zMyZc2ZmZLVUaFn6a2R06ZGlHmBrpvnBvb71fWQHVOSwPbf4GS46TajJspRlVhjZU1HqkhQSWPkHIYdXS5xw-Zas3ueI6FRn7qHFS11_xSRZhIxbFtcDtw7SJb1iXaOg5XIFeQGjzyPRaevYNOGZIJ8qogbpe8CWiy_VzEpTXiQUcvPDkSVrSNZz1UlW1N5eLcqmpdXUvaQ4BmqlhZNUCgxuzFHDqUWNAxrYeUM76AzsnOsdiJbrBp_71lKpn3RRbii-4P3f-IMsRxS-wcDV_bL4PmSdBa2wl7pKnbp8DMgVvJm8ZNskKRkEM_OzyOKQFkgqOYBQ3Nq89Ns0nbIl81vMFN-jKoLMTOr-SOBOJS-Z8f5Y6D1wdcR8dFqvEBdetK-PHwj-z-cH8oHPY54wRJ8Ys7iSQ3Bg3VA9azQbmC9k35kKzYa6PoVtfwbbKVnBixBiGn7Pq0rqJoUtHiCZwAM3jdTPWCVtr_glhVrhecIa3vuksJ_b7TqFs4DPyriSjd5IwoNNQaAmNI-ESfR2p8zimzvN1swdCkvJHPH6-_oX8o1SgcIDAAA=)). ```svelte ``` Les ré-exécutions sont mutualisées (i.e. changer `color` et `size` au même moment ne va pas déclencher deux ré-exécutions distinctes), et se produisent après que les éventuelles modifications du DOM aient eu lieu. Vous pouvez places des `$effect` n'importe où, pas uniquement à la racine d'un composant, tant qu'il est exécuté lors de l'initialisation du composant (ou lorsqu'un effet parent est actif). Il est ensuite attaché au cycle de vie du composant (ou de l'effet parent) et sera donc détruit lorsque du démontage du composant (ou lorsque l'effet parent est détruit). Vous pouvez renvoyer une fonction depuis `$effect`, qui sera immédiatement exécutée avant la ré-exécution de l'effet, et lorsque celui-ci est détruit ([démo](/playground/untitled#H4sIAAAAAAAAE42RQY-bMBCF_8rI2kPopiXpMQtIPfbeW6m0xjyKtWaM7CFphPjvFVB2k2oPe7LmzXzyezOjaqxDVKefo5JrD3VaBLVXrLu5-tb3X-IZTmat0hHv6cazgCWqk8qiCbaXouRSHISMH1gop4coWrA7JE9bp7PO2QjjuY5vA8fDYZ3hUh7QNDCy2yWUFzTOUilpSj9aG-linaMKFGACtKCmSwvGGYGeLQvCWbtnMq3m34grajxHoa1JOUXI93_V_Sfz7Oz7Mafj0ypN-zvHm8dSAmQITP_xaUq2IU1GO1dp80I2Uh_82dao92Rl9R8GvgF0QrbrUFstcFeq0PgAkha0LoICPoeB4w1SJUvsZcj4rvcMlvmvGlGCv6J-DeSgw2vabQnJlm55p7nM0rcTctYei3HZxZSl7XHVqkHEM3k2zpqXfFyj393zU05fpyI6f0HI0hUoPoamC9roKDeo2ivBH1EnCQOmX9NfYw2GHrgCAAA=)) ```svelte

{count}

``` ### Comprendre les dépendances [!VO]Understanding dependencies `$effect` détecte automatiquement toute valeur réactive (`$state`, `$derived`, `$props`) qui est lue de manière _synchrone_ à l'intérieur de son corps de fonction et l'enregistre en tant que dépendance. Lorsque ces dépendances changent, l'`$effect` va planifier une ré-exécution. Les valeurs qui sont lues de manière _asynchrones_ — après un `await` ou à l'intérieur d'un `setTimeout`, par exemple — ne seront pas considérées comme dépendances. Ici, le canvas sera repeint lorsque `color` change, mais pas lorsque `size` change ([démo](/playground/untitled#H4sIAAAAAAAAE31T246bMBD9lZF3pWSlBEirfaEQqdo_2PatVIpjBrDkGGQPJGnEv1e2IZfVal-wfHzmzJyZ4cIqqdCy9M-F0blDlnqArZjmB3f72XWRHVCRw_bc4me4aDWhJstSlllhZEfbQhekkMDKfwg5PFvihMvX5OXH_CJa1Zrb0-Kpqr5jkiwC48rieuDWQbqgZ6wqFLRcvkC-hYvnkWi1dWqa8ESQTxFRjfQWsOXiWzmr0sSLhEJu3p1YsoJkNUcdZUnN9dagrBu6FVRQHAM10sJRKgUG16bXcGxQ44AGdt7SDkTDdY02iqLHnJVU6hedlWuIp94JW6Tf8oBt_8GdTxlF0b4n0C35ZLBzXb3mmYn3ae6cOW74zj0YVzDNYXRHFt9mprNgHfZSl6mzml8CMoLvTV6wTZIUDEJv5us2iwMtiJRyAKG4tXnhl8O0yhbML0Wm-B7VNlSSSd31BG7z8oIZZ6dgIffAVY_5xdU9Qrz1Bnx8fCfwtZ7v8Qc9j3nB8PqgmMWlHIID6-bkVaPZwDySfWtKNGtquxQ23Qlsq2QJT0KIqb8dL0up6xQ2eIBkAg_c1FI_YqW0neLnFCqFpwmreedJYT7XX8FVOBfwWRhXstZrSXiwKQjUhOZeMIleb5JZfHWn2Yq5pWEpmR7Hv-N_wEqT8hEEAAA=)) : ```ts // @filename: index.ts declare let canvas: { width: number; height: number; getContext(type: '2d', options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D; }; declare let color: string; declare let size: number; // ---cut--- $effect(() => { const context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); // cet effet sera rejoué lorsque `color` change... context.fillStyle = color; setTimeout(() => { // ... mais pas lorsque `size` change context.fillRect(0, 0, size, size); }, 0); }); ``` Un effet est seulement rejoué lorsque l'objet qu'il lit change, pas lorsqu'une propriété de cet objet change. (If vous souhaitez observer les changement _à l'intérieur_ d'un objet lors de vos développements, vous pouvez utiliser [`$inspect`]($inspect).) ```svelte

Le double de {state.value} vaut {derived.value}

``` Un effet dépend uniquement des valeurs qu'il a lues la dernière fois qu'il a été joué. Ceci a des conséquences intéressantes pour les effets qui impliquent du code conditionnel. Par exemple, si `a` vaut `true` dans le code ci-dessous, le code dans le bloc `#if` sera joué et `b` sera ré-évalué. Dans ce cas, n'importe quel changement sur `a` ou `b` [va déclencher la ré-exécution de l'effet](/playground/untitled#H4sIAAAAAAAAE3VQzWrDMAx-FdUU4kBp71li6EPstOxge0ox8-QQK2PD-N1nLy2F0Z2Evj9_chKkP1B04pnYscc3cRCT8xhF95IEf8-Vq0DBr8rzPB_jJ3qumNERH-E2ECNxiRF9tIubWY00lgcYNAywj6wZJS8rtk83wjwgCrXHaULLUrYwKEgVGrnkx-Dx6MNFNstK5OjSbFGbwE0gdXuT_zGYrjmAuco515Hr1p_uXak3K3MgCGS9s-9D2grU-judlQYXIencnzad-tdR79qZrMyvw9wd5Z8Yv1h09dz8mn8AkM7Pfo0BAAA=). À l'inverse, si `a` vaut `false`, `b` ne sera pas ré-évalué, et l'effet ne sera rejoué _que si_ `a` change. ```ts let a = false; let b = false; // ---cut--- $effect(() => { console.log('effet'); if (a) { console.log('b:', b); } }); ``` ## `$effect.pre` Dans de rares cas, vous pourriez avoir besoin d'exécuter votre code _avant_ que le DOM ne soit mis à jour. Pour cela, nous avons accès à la rune `$effect.pre` : ```svelte
{#each messages as message}

{message}

{/each}
``` Le timing mis à part, `$effect.pre` fonctionne exactement comme `$effect`. ## `$effect.tracking` La rune `$effect.tracking` est une fonctionnalité avancée qui vous informe de si le code est exécuté au sein d'un contexte de suivi (_tracking_), comme un effet ou bien dans le template ([démo](/playground/untitled#H4sIAAAAAAAACn3PwYrCMBDG8VeZDYIt2PYeY8Dn2HrIhqkU08nQjItS-u6buAt7UDzmz8ePyaKGMWBS-nNRcmdU-hHUTpGbyuvI3KZvDFLal0v4qvtIgiSZUSb5eWSxPfWSc4oB2xDP1XYk8HHiSHkICeXKeruDDQ4Demlldv4y0rmq6z10HQwuJMxGVv4mVVXDwcJS0jP9u3knynwtoKz1vifT_Z9Jhm0WBCcOTlDD8kyspmML5qNpHg40jc3fFryJ0iWsp_UHgz3180oBAAA=)) : ```svelte

dans le template: {$effect.tracking()}

``` C'est notamment utilisé pour implémenter des abstractions comme [`createSubscriber`](/docs/svelte/svelte-reactivity#createSubscriber), qui servent à créer des gestionnaires permettant de mettre à jour des valeurs réactives _seulement_ si ces valeurs sont trackées (plutôt que, par exemple, simplement lues dans un gestionnaire d'évènement). ## `$effect.root` La rune `$effect.root` est une fonctionnalité avancée qui crée un scope non suivi qui ne s'auto-nettoie pas. Cela est utile pour les effets imbriqués que vous souhaitez contrôler manuellement. Cette rune permet également la création d'effets en dehors de la phase d'initialisation du composant. ```svelte ``` ## Quand ne pas utiliser `$effect` [!VO]When not to use `$effect` En général, `$effect` est plutôt considéré comme un dernier recours — pratique pour des choses comme les analytics ou la manipulation directe du DOM — plutôt qu'un outil que vous devriez utiliser souvent. En particulier, évitez de vous en servir pour synchroniser un état. Plutôt que faire ceci... ```svelte ``` ... faites ceci : ```svelte ``` > [!NOTE] Pour des choses plus compliquées qu'une simple expression comme `count * 2`, vous pouvez > aussi utiliser `$derived.by`. Vous pourriez être tenté•e de faire des choses tordues avec les effets pour lier une valeur à une autre. L'exemple suivant montre deux inputs pour "argent dépensé" et "argent restant" qui sont connectés l'un à l'autre. Si vous en mettez un à jour, l'autre s'ajuste automatiquement. N'utilisez pas d'effets pour faire ça ([démo](/playground/untitled#H4sIAAAAAAAACpVRy26DMBD8FcvKgUhtoIdeHBwp31F6MGSJkBbHwksEQvx77aWQqooq9bgzOzP7mGTdIHipPiZJowOpGJAv0po2VmfnDv4OSBErjYdneHWzBJaCjcx91TWOToUtCIEE3cig0OIty44r5l1oDtjOkyFIsv3GINQ_CNYyGegd1DVUlCR7oU9iilDUcP8S8roYs9n8p2wdYNVFm4csTx872BxNCcjr5I11fdgonEkXsjP2CoUUZWMv6m6wBz2x7yxaM-iJvWeRsvSbSVeUy5i0uf8vKA78NIeJLSZWv1I8jQjLdyK4XuTSeIdmVKJGGI4LdjVOiezwDu1yG74My8PLCQaSiroe5s_5C2PHrkVGAgAA). ```svelte ``` Utilisez plutôt des callbacks lorsque c'est possible ([démo](/playground/untitled#H4sIAAAAAAAACo1SMW6EMBD8imWluFMSIEUaDiKlvy5lSOHjlhOSMRZeTiDkv8deMEEJRcqdmZ1ZjzzxqpZgePo5cRw18JQA_sSVaPz0rnVk7iDRYxdhYA8vW4Wg0NnwzJRdrfGtUAVKQIYtCsly9pIkp4AZ7cQOezAoEA7JcWUkVBuCdol0dNWrEutWsV5fHfnhPQ5wZJMnCwyejxCh6G6A0V3IHk4zu_jOxzzPBxBld83PTr7xXrb3rUNw8PbiYJ3FP22oTIoLSComq5XuXTeu8LzgnVA3KDgj13wiQ8taRaJ82rzXskYM-URRlsXktejjgNLoo9e4fyf70_8EnwncySX1GuunX6kGRwnzR_BgaPNaGy3FmLJKwrCUeBM6ZUn0Cs2mOlp3vwthQJ5i14P9st9vZqQlsQIAAA==)). ```svelte ``` Si vous avez besoin d'utiliser des liaisons, peu importe la raison (par exemple lorsque vous voulez quelque chose comme un `$derived` que l'on peut modifier manuellement), envisagez l'utilisation de getters et setters pour synchroniser l'état ([démo](/playground/untitled#H4sIAAAAAAAACpWRwW6DMBBEf8WyekikFOihFwcq9TvqHkyyQUjGsfCCQMj_XnvBNKpy6Qn2DTOD1wu_tRocF18Lx9kCFwT4iRvVxenT2syNoDGyWjl4xi93g2AwxPDSXfrW4oc0EjUgwzsqzSr2VhTnxJwNHwf24lAhHIpjVDZNwy1KS5wlNoGMSg9wOCYksQccerMlv65p51X0p_Xpdt_4YEy9yTkmV3z4MJT579-bUqsaNB2kbI0dwlnCgirJe2UakJzVrbkKaqkWivasU1O1ULxnOVk3JU-Uxti0p_-vKO4no_enbQ_yXhnZn0aHs4b1jiJMK7q2zmo1C3bTMG3LaZQVrMjeoSPgaUtkDxePMCEX2Ie6b_8D4WyJJEwCAAA=)). ```svelte ``` Si vous devez absolument mettre à jour un `$state` dans un effet et que cela déclenche une boucle infinie parce que vous lisez et écrivez un même `$state`, utilisez [untrack](svelte#untrack). # $props Les données d'entrée d'un composant sont appelées des _props_, abbréviation de _propriétés_. Vous pouvez fournir des props aux composants de la même manière que vous passeriez des attributs aux éléments : ```svelte ``` De l'autre côté, dans `MyComponent.svelte`, les props sont accessibles grâce à la rune `$props`... ```svelte

ce composant est {props.adjective}

``` ... bien que plus souvent, il est plus pratique de [déstructurer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) vos props : ```svelte

ce composant est {+++adjective+++}

``` ## Valeurs par défaut [!VO]Fallback values Déstructurer permet de déclarer des valeurs par défaut, qui sont utilisées si le composant parent ne définit pas une prop donnée : ```js let { adjective = 'content' } = $props(); ``` > [!NOTE] Les valeurs par défaut ne sont pas transformées en proxys d'état réactifs (voir [Mise à > jour des props](#Updating-props) pour plus d'infos). ## Renommer des props [!VO]Renaming props Vous pouvez aussi utiliser la syntaxe d'assignation par déstructuration pour renommer des props, ce qui est nécessaire si leur identifiant est invalide ou si c'est un mot-clé réservé par JavaScript, comme `super` : ```js let { super: trouper = 'lights are gonna find me' } = $props(); ``` ## Props de reste [!VO]Rest props Enfin, nous pouvons utiliser une _propriété de reste_ pour obtenir, eh bien, le reste des props : ```js let { a, b, c, ...others } = $props(); ``` ## Mise à jour des props [!VO]Updating props Les références à une prop à l'intérieur d'un composant se mettent à jour lorque la prop elle-même se met à jour — lorsque `count` change dans `App.svelte`, elle va également changer dans `Child.svelte`. Mais le composant enfant est capable d'écraser la valeur de la prop, ce qui peut être utile pour des états temporaires qui ne seront pas sauvegardés ([démo](/playground/untitled#H4sIAAAAAAAAE6WQ0WrDMAxFf0WIQR0Wmu3VTQJln7HsIfVcZubIxlbGRvC_DzuBraN92qPula50tODZWB1RPi_IX16jLALWSOOUq6P3-_ihLWftNEZ9TVeOWBNHlNhGFYznfqCBzeRdYHh6M_YVzsFNsNs3pdpGd4eBcqPVDMrNxNDBXeSRtXioDgO1zU8ataeZ2RE4Utao924RFXQ9iHXwvoPHKpW1xY4g_Bg0cSVhKS0p560Za95612ZC02ONrD8ZJYdZp_rGQ37ff_mSP86Np2TWZaNNmdcH56P4P67K66_SXoK9pG-5dF5Z9QEAAA==)). ```svelte ``` ```svelte ``` Bien que vous puissiez temporairement _réassigner_ des props, vous ne devriez pas _muter_ de props, à moins qu'elles soient définies comme [bindable]($bindable). Si une props est un objet classique, la mutation n'aura aucun effet ([démo](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2W1QmorQgJXk0RC3PkBwiExG9WQrC17U4Es_ztKUkQp9OjxzM7bjcjtSKjwyfKNp1aLORA4b13ADHszUED1HFE-3eyaBcy-Mw_O5eFAg8xa1wb6T9eWhVgCKiyD9sZJ3XAjZnTWCzzuzfAKvbcjbPJieR2jm_uGy-InweXqtd0baaliBG0nFgW3kBIUNWYo9CGoxE-UsgvIpw2_oc9-LmAPJBCPDJCggqvlVtvdH9puErEMlvVg9HsVtzuoaojzkKKAfRuALVDfk5ZZW0fmy05wXcFdwyktlUs-KIinljTXrRVnm7-kL9dYLVbUAQAA) : ```svelte ``` ```svelte ``` Toutefois, si la props est un proxy réactif, les mutations _auront_ un effet, mais vous aurez un warning [`_ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation), car le composant mute un état qui ne lui "appartient" pas ([démo](/playground/untitled#H4sIAAAAAAAAE3WR0U7DMAxFf8VESBuiauG1WycheOEbKA9p67FA6kSNszJV-XeUZhMw2GN8r-1znUmQ7FGU4pn2UqsOes-SlSGRia3S6ET5Mgk-2OiJBZGdOh6szd0eNcdaIx3-V28NMRI7UYq1awdleVNTzaq3ZmB43CndwXYwPSzyYn4dWxermqJRI4Np3rFlqODasWRcTtAaT1zCHYSbVU3r4nsyrdPMKTUFKDYiE4yfLEoePIbsQpqfy3_nOVMuJIqg0wk1RFg7GOuWfwEbz2wIDLVatR_VtLyBagNTHFIUMCqtoZXeIfAOU1JoUJsR2IC3nWTMjt7GM4yKdyBhlAMpesvhydCC0y_i0ZagHByMh26WzUhXUUxKnpbcVnBfUwhznJnNlac7JkuIURL-2VVfwxflyrWcSQIAAA==)) : ```svelte ``` ```svelte ``` La valeur par défaut d'une prop non déclarée avec `$bindable` n'est pas affectée — elle n'est pas tranformée en proxy réactif d'état — ce qui implique que les mutations ne provoqueront pas de mise à jour ([démo](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2VkIbUVoYFraCIh7vwA4eC4G9Wta1vxpgJZ_nfkBEQp9OjxzOzTRGHlkUQlXpy9G0gq1idCL43ppDrAD84HUYheGwqieo2CP3y2Z0EU3-En79fhRIaz1slA_-nKWSbLQVRiE9SgPTetbVkfvRsYzztttugHd8RiXU6vr-jisbWb8idhN7O3bEQhmN5ZVDyMlIorcOddv_Eufq4AGmJEuG5PilEjQrnRcoV7JCTUuJlGWq7-YHYjs7NwVhmtDnVcrlA3iLmzLLGTAdaB-j736h68Oxv-JM1I0AFjoG1OzPfX023c1nhobUoT39QeKsRzS8owM8DFTG_pE6dcVl70AQAA)) : ```svelte ``` En résumé : ne mutez pas les props. Vous pouvez soit utiliser des props de callback pour communiquer des changements, ou — si le parent et l'enfant partagent le même objet — utiliser la rune [`$bindable`]($bindable). ## Typage [!VO]Type safety Vous pouvez ajouter du typage à vos composants en annotant vos props, comme vous le feriez avec toute autre déclaration de variable. En TypeScript, cela peut ressembler à ça... ```svelte ``` ... tandis qu'en JSDoc vous pouvez écrire ceci : ```svelte ``` Vous pouvez, bien sûr, séparer la déclaration de type de l'annotation : ```svelte ``` > [!NOTE] Les interfaces des éléments natifs du DOM sont fournies par le module `svelte/elements` > (voir [Typer des composants haut-niveau](typescript#Typing-wrapper-components)). L'ajout de types est recommandé, car il permet aux personnes utilisant votre composant de découvrir facilement les props à fournir. # $bindable D'ordinaire, les props se déplacent dans un seul sens, du parent vers l'enfant. Ceci permet de clarifier la manière dont les données circulent au sein de votre application. Avec Svelte, les props de composant peuvent être _liées_ (_"bound"_), ce qui signifie que les données peuvent également remonter de l'enfant vers le parent. Ce n'est pas quelque chose que vous devriez faire trop souvent, mais cela peut simplifier votre code si utilisé de manière sporadique et précautionneuse. Cela signifie aussi qu'un proxy d'état peut être _muté_ dans l'enfant. > [!NOTE] La mutation est aussi possible avec des props normales, mais est fortement déconseillée – > Svelte vous préviendra si son compilateur détecte qu'un composant mute un état qu'il ne "contrôle" > pas. Pour déclarer une prop comme pouvant être liée ("bindable"), il faut utiliser la rune `$bindable` : ```svelte /// file: FancyInput.svelte ``` Désormais, un composant qui utilise `` peut ajouter la directive [`bind`](bind) ([démo(/playground/untitled#H4sIAAAAAAAAE3WQwWrDMBBEf2URBSfg2nfFMZRCoYeecqx6UJx1IyqvhLUONcb_XqSkTUOSk1az7DBvJtEai0HI90nw6FHIJIhckO7i78n7IhzQctS2OuAtvXHESByEFFVoeuO5VqTYdN71DC-amvGV_MDQ9q6DrCjP0skkWymKJxYZOgxBfyKs4SGwZlxke7TWZcuVoqo8-1P1z3lraCcP2g64nk4GM5S1osrXf0JV-lrkgvGbheR-wDm_g30V8JL-1vpOCZFogpQsEsWcemtxscyhKArfOx9gjps0Lq4hzRVfemaYfu-PoIqqwKPFY_XpaIqj4tYRP7a6M3aUkD27zjSw0RTgbZN6Z8WNs66XsEP03tBXUueUJFlelvYx_wCuI3leNwIAAA==)]) ```svelte /// App.svelte

{message}

``` Le composant parent n'est pas _obligé_ d'utiliser `bind:` — il peut se contenter de fournir une prop normale. Certains parents n'ont pas envie d'écouter ce que leurs enfants ont à leur dire. Dans ce cas, vous pouvez préciser une valeur par défaut à utiliser lorsqu'aucune prop n'est fournie : ```js /// file: FancyInput.svelte let { value = $bindable('défaut'), ...props } = $props(); ``` # $inspect > [!NOTE] `$inspect` ne fonctionne que lors du développement. Dans un build de production, ell n'est > jamais exécutée. La rune `$inspect` est plus ou moins équivalente à `console.log`, si ce n'est qu'elle va déclencher sa ré-exécution si sont argument est mis à jour. `$inspect` suit les changements d'états reactifs de manière profonde, ce qui signifie que mettre à jour quelque chose au sein d'un objet ou d'un tableau en utilisant la réactivité fine va déclencher sa ré-exécution ([démo](/playground/untitled#H4sIAAAAAAAACkWQ0YqDQAxFfyUMhSotdZ-tCvu431AXtGOqQ2NmmMm0LOK_r7Utfby5JzeXTOpiCIPKT5PidkSVq2_n1F7Jn3uIcEMSXHSw0evHpAjaGydVzbUQCmgbWaCETZBWMPlKj29nxBDaHj_edkAiu12JhdkYDg61JGvE_s2nR8gyuBuiJZuDJTyQ7eE-IEOzog1YD80Lb0APLfdYc5F9qnFxjiKWwbImo6_llKRQVs-2u91c_bD2OCJLkT3JZasw7KLA2XCX31qKWE6vIzNk1fKE0XbmYrBTufiI8-_8D2cUWBA_AQAA)). ```svelte ``` ## $inspect(...).with `$inspect` renvoie une propriété `with`, que vous pouvez exécuter avec un callback, qui sera ensuite utilisé à la place de `console.log`. Le premier argument du callback est soit `"init"` ou `"update"` ; les arguments suivants sont les valeurs passées à `$inspect` ([démo](/playground/untitled#H4sIAAAAAAAACkVQ24qDMBD9lSEUqlTqPlsj7ON-w7pQG8c2VCchmVSK-O-bKMs-DefKYRYx6BG9qL4XQd2EohKf1opC8Nsm4F84MkbsTXAqMbVXTltuWmp5RAZlAjFIOHjuGLOP_BKVqB00eYuKs82Qn2fNjyxLtcWeyUE2sCRry3qATQIpJRyD7WPVMf9TW-7xFu53dBcoSzAOrsqQNyOe2XUKr0Xi5kcMvdDB2wSYO-I9vKazplV1-T-d6ltgNgSG1KjVUy7ZtmdbdjqtzRcphxMS1-XubOITJtPrQWMvKnYB15_1F7KKadA_AQAA)) ```svelte ``` Une manière pratique de trouver l'origine d'une mise à jour est de fournir `console.trace` à `with` : ```js // @errors: 2304 $inspect(stuff).with(console.trace); ``` ## $inspect.trace(...) Cette rune, ajoutée avec la version 5.14, déclenche le _suivi_ de la fonction passée en argument. À chaque fois que la fonction est rejouée dans le cadre d'un [effet]($effect) ou d'une [dérivation]($derived), des informations concernant les états réactifs ayant généré l'effet seront affichées dans la console. ```svelte ``` `$inspect.trace` prend un argument optionnel qui peut être utilisé comme label. # $host Lorsque vous compilez un composant en tant que élément personnalisé, la rune `$host` fournit un accès à l'élément hôte, vous permettant (par exemple) de générer des évènements personnalisés ([démo](/playground/untitled#H4sIAAAAAAAAE41Ry2rDMBD8FSECtqkTt1fHFpSSL-ix7sFRNkTEXglrnTYY_3uRlDgxTaEHIfYxs7szA9-rBizPPwZOZwM89wmecqxbF70as7InaMjltrWFR3mpkQDJ8pwXVnbKkKiwItUa3RGLVtk7gTHQXRDR2lXda4CY1D0SK9nCUk0QPyfrCovsRoNFe17aQOAwGncgO2gBqRzihJXiQrEs2csYOhQ-7HgKHaLIbpRhhBG-I2eD_8ciM4KnnOCbeE5dD2P6h0Dz0-Yi_arNhPLJXBtSGi2TvSXdbpqwdsXvjuYsC1veabvvUTog2ylrapKH2G2XsMFLS4uDthQnq2t1cwKkGOGLvYU5PvaQxLsxOkPmsm97Io1Mo2yUPF6VnOZFkw1RMoopKLKAE_9gmGxyDFMwMcwN-Bx_ABXQWmOtAgAA)). ```svelte /// file: Stepper.svelte ``` ```svelte /// file: App.svelte count -= 1} onincrement={() => count += 1} >

compte : {count}

``` # Bases du markup Le markup présent dans un composant Svelte peut être vu comme du HTML++. ## Balises [!VO]Tags Une balise en minuscules, comme `
`, représente un élément HTML standard. Une balise en majuscules ou une balise utilisant un point, comme `` ou ``, représente un _composant_. ```svelte
``` ## Attributs des éléments [!VO]Element attributes Par défaut, les attributs fonctionnent exactement comme leurs homologues HTML. ```svelte
``` Comme en HTML, les valeurs peuvent être fournies sans guillemets. ```svelte ``` Les valeurs d'attributs peuvent contenir des expressions JavaScript. ```svelte page {p} ``` Ou peuvent _être_ des expressions JavaScript. ```svelte ``` Les attributs booléens sont inclus sur l'élément si leur valeur est [truthy](https://developer.mozilla.org/fr/docs/Glossary/Truthy) et exclus si leur valeur est [falsy](https://developer.mozilla.org/fr/docs/Glossary/Falsy). Tous les autres attributs sont inclus sauf si leur valeur est [nullish](https://developer.mozilla.org/fr/docs/Glossary/Nullish) (`null` ou `undefined`). ```svelte
Cette div n'a pas d'attribut de titre
``` > [!NOTE] Mettre une expression entre guillemets n'a pas d'effet sur comment la valeur est lue, mais > en Svelte 6 cela entraînera la transformation de la valeur en string : > > > ```svelte > > ``` Lorsque le nom de l'attribut correspond au nom de sa valeur (`name={name}`), l'écriture peut être remplacée par `{name}`. ```svelte ``` ## Props de composant [!VO]Component props Par convention, les valeurs passées aux composants sont appelées _propriétés_, ou _props_, plutôt qu'_attributs_, qui sont une fonctionnalité du DOM. Comme pour les éléments, `name={name}` peut être remplacé par le raccourci `{name}`. ```svelte ``` Les _attributs décomposés_ permettre de fournir d'un coup plusieurs attributs ou propriétés à un élément ou composant. Un élément ou composant peut avoir plusieurs attributs décomposés, ponctués d'attributs normaux. ```svelte ``` ## Évènements [!VO]Events Écouter des évènements DOM est possible en ajoutant à un élément des attributs commençant par `on`. Par exemple, pour écouter l'évènement `click`, ajoutez l'attribut `onclick` à un bouton : ```svelte ``` Les attributs d'évènements sont sensibles à la casse. `onclick` écoute l'évènement `click`, `onClick` écoute l'évènement `Click`, ce qui n'est pas la même chose. Ceci vous assure de pouvoir écouter des évènements personnalisés ayant des majuscules dans leur nom. Puisque les évènements sont juste des attributs, les règles des attributs s'appliquent : - vous pouvez utiliser la forme raccourcie : `` - vous pouvez les décomposer : `` En termes de timing, les attributs d'évènement sont toujours déclenchés après les évènements venant de liaisons (par ex. `oninput` est toujours déclenché après une mise à jour via `bind:value`). Sous le capot, certains gestionnaires d'évènement sont directement attachés avec `addEventListener`, tandis que d'autres sont _délégués_. Lors de l'utilisation d'attributs d'évènement `ontouchstart` et `ontouchmove`, les gestionnaires sont [passifs](https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) pour des raisons de performance. Cela améliore notablement la responsivité en laissant le navigateur parcourir le document immédiatement, plutôt que d'attendre de savoir si le gestionnaire d'évènement exécute `event.preventDefault()`. Dans les rares cas où vous auriez besoin d'empêcher le comportement par défaut de ces évènements, vous devriez plutôt utiliser [`on`](svelte-events#on) (par exemple dans une action). ### Délégation d'évènement [!VO]Event delegation Pour réduire l'empreinte mémoire et améliorer les performances, Svelte utilise une technique appelée délégation d'évènement. Ceci signifie que pour certains évènements — voir la liste plus bas — un unique gestionnaire d'évènement "racine" prend la responsabilité de jouer tout gestionnaire présent dans le parcours de l'évènement. Il y a quelques inconvénients à avoir en tête : - lorsque vous générez manuellement un évènement avec un gestionnaire délégué, assurez-vous de définir l'option `{ bubbles: true }` ou bien l'évènement n'atteindra jamais la racine de l'application. - lorsque vous utilisez `addEventListener` directement, éviter d'appeler `stopPropagation` ou bien l'évènement n'atteindra pas la racine de l'application et les gestionnaires ne seront pas invoqués. De même, les gestionnaires ajoutés manuellement à la racine de l'application seront exécutés _avant_ les gestionnaires ajoutés déclarativement plus profondément dans le DOM (c-à-d avec `onclick={...}`), à la fois pour les phases de capture et de bubbling. C'est pour ces raisons qu'il est préférable d'utiliser la fonction `on` importée depuis `svelte/events` plutôt que d'utiliser `addEventListener`, puisque cela vous assurera que l'ordre est préservé et que `stopPropagation` est géré correctement. Les gestionnaires des évènements suivants sont délégués : - `beforeinput` - `click` - `change` - `dblclick` - `contextmenu` - `focusin` - `focusout` - `input` - `keydown` - `keyup` - `mousedown` - `mousemove` - `mouseout` - `mouseover` - `mouseup` - `pointerdown` - `pointermove` - `pointerout` - `pointerover` - `pointerup` - `touchend` - `touchmove` - `touchstart` ## Expressions texte [!VO]Text expressions Une expression JavaScript peut être incluse en tant que texte en l'entourant d'accolades. ```svelte {expression} ``` Les accolades peuvent être incluses dans un template Svelte en utilisant leur chaîne de caractères d'[entité HTML](https://developer.mozilla.org/fr/docs/Glossary/Entity) : `{`, `{`, or `{` pour `{` et `}`, `}`, ou `}` pour `}`. Si vous utilisez la [notation litérale](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor) d'une expression régulière (`RegExp`), vous devrez l'entourer de parenthèses : ```svelte

Hello {name}!

{a} + {b} = {a + b}.

{(/^[A-Za-z ]+$/).test(value) ? x : y}
``` L'expression sera transformée en chaîne de caractères et échappée pour éviter les injections de code. Si vous souhaitez afficher du HTML, utilisez plutôt la balise `{@html}`. ```svelte {@html uneChaineDeCaracteresPotentiellementDangereuse} ``` > [!NOTE] Assurez-vous soit d'échapper la chaîne fournie, soit de ne fournir que des valeurs qui > sont sous votre contrôle pour votre protéger d'éventuelles attaques > [XSS](https://owasp.org/www-community/attacks/xss/). ## Commentaires [!VO]Comments Vous pouvez écrire des commentaires HTML au sein de vos composants. ```svelte

Coucou tout le monde

``` Les commentaires commençant par `svelte-ignore` désactivent les warnings pour le bloc de markup suivant. Ces sont généralement des warnings d'accessibilité ; ne les désactivez que pour une bonne raison. ```svelte ``` Vous pouvez ajouter un commentaire spécial commençant par `@component` qui s'affichera lorsque vous survolerez le nom du composant dans d'autres fichiers. ````svelte

Coucou {name}

```` # {#if ...} ```svelte {#if expression}...{/if} ``` ```svelte {#if expression}...{:else if expression}...{/if} ``` ```svelte {#if expression}...{:else}...{/if} ``` Le contenu qui est affiché conditionnellement peut être disposé dans un bloc `#if`. ```svelte {#if answer === 42}

vous pouvez répéter la question ?

{/if} ``` D'autres conditions peuvent être ajoutées avec `{:else if expression}`, et éventuellement finalisées par une clause `{:else}`. ```svelte {#if porridge.temperature > 100}

trop chaud !

{:else if 80 > porridge.temperature}

trop froid !

{:else}

parfait !

{/if} ``` (Les blocs n'ont pas besoin de contenir des éléments, ils peuvent aussi simplement contenir du texte dans des éléments.) # {#each ...} ```svelte {#each expression as name}...{/each} ``` ```svelte {#each expression as name, index}...{/each} ``` Vous pouvez itérer sur des valeurs en utilisant un bloc `#each`. Les valeurs en questions peuvent être des tableaux, des objets similaires à des tableaux (c-à-d tout ce qui possède une propriété `length`), ou des itérables comme `Map` et `Set` — autrement dit, tout ce qui peut être utilisé avec `Array.from`. ```svelte

Shopping list

    {#each items as item}
  • {item.name} x {item.qty}
  • {/each}
``` Un bloc `#each` peut également préciser un _index_, correspondant au deuxième argument d'un callback `array.map(...)`. ```svelte {#each items as item, i}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} ``` ## Les blocs `each` à clé [!VO]Keyed each blocks ```svelte {#each expression as name (key)}...{/each} ``` ```svelte {#each expression as name, index (key)}...{/each} ``` Si une expression _key_ est fournie — qui se doit d'identifier de manière unique chaque élément de la liste — Svelte va s'en servir pour remplacer finement les éléments de la liste lorsque celle-ci change, plutôt que d'ajouter ou supprimer les éléments à la fin. La clé (_key_) peut être n'importe quel objet, mais les chaînes de caractères et les nombres sont recommandés car il permettent à l'identité de persister lorsque les objets eux-mêmes changent. ```svelte {#each items as item (item.id)}
  • {item.name} x {item.qty}
  • {/each} {#each items as item, i (item.id)}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} ``` Vous pouvez déstructurer librement ou utiliser comme bon vous semble le paramètre de reste dans les blocs `#each`. ```svelte {#each items as { id, name, qty }, i (id)}
  • {i + 1}: {name} x {qty}
  • {/each} {#each objects as { id, ...rest }}
  • {id}
  • {/each} {#each items as [id, ...rest]}
  • {id}
  • {/each} ``` ## Blocs `each` sans élément [!VO]Each blocks without an item ```svelte {#each expression}...{/each} ``` ```svelte {#each expression, index}...{/each} ``` Dans le cas où vous souhaitez uniquement afficher quelque chose `n` fois, vous pouvez omettre le `as` ([demo](/playground/untitled#H4sIAAAAAAAAE3WR0W7CMAxFf8XKNAk0WsSeUEaRpn3Guoc0MbQiJFHiMlDVf18SOrZJ48259_jaVgZmxBEZZ28thgCNFV6xBdt1GgPj7wOji0t2EqI-wa_OleGEmpLWiID_6dIaQkMxhm1UdwKpRQhVzWSaVORJNdvWpqbhAYVsYQCNZk8thzWMC_DCHMZk3wPSThNQ088I3mghD9UwSwHwlLE5PMIzVFUFq3G7WUZ2OyUvU3JOuZU332wCXTRmtPy1NgzXZtUFp8WFw9536uWqpbIgPEaDsJBW90cTOHh0KGi2XsBq5-cT6-3nPauxXqHnsHJnCFZ3CvJVkyuCQ0mFF9TZyCQ162WGvteLKfG197Y3iv_pz_fmS68Hxt8iPBPj5HscP8YvCNX7uhYCAAA=)): ```svelte
    {#each { length: 8 }, rank} {#each { length: 8 }, file}
    {/each} {/each}
    ``` ## Blocs `else` [!VO]Else blocks ```svelte {#each expression as name}...{:else}...{/each} ``` Un bloc `#each` peut également avoir une clause `{:else}`, qui sera affichée si la liste est vide. ```svelte {#each todos as todo}

    {todo.text}

    {:else}

    Rien à faire aujourd'hui !

    {/each} ``` # {#key ...} ```svelte {#key expression}...{/key} ``` Les blocs `key` détruisent et recréent leur contenu lorsque la valeur d'une expression change. Lorsqu'utilisés autour de composants, ils déclenchent leur réinstanciation et réinitialisation : ```svelte {#key value} {/key} ``` C'est également utile si vous souhaitez déclencher une transition à chaque fois qu'une valeur change : ```svelte {#key value}
    {value}
    {/key} ``` # {#await ...} ```svelte {#await expression}...{:then name}...{:catch name}...{/await} ``` ```svelte {#await expression}...{:then name}...{/await} ``` ```svelte {#await expression then name}...{/await} ``` ```svelte {#await expression catch name}...{/await} ``` Les blocs `await` vous permettent de gérer les trois états possible d'une [`Promise`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise) (_promesse_) — en attente, résolue, ou rejetée. ```svelte {#await promise}

    en attente de la résolution de la promesse...

    {:then value}

    La valeur vaut {value}

    {:catch error}

    Quelque chose s'est mal passé : {error.message}

    {/await} ``` > [!NOTE] Lors du rendu côté serveur, seule la branche d'attente sera considérée. > > Si l'expression fournie n'est pas une `Promise`, seule la branche `:then` sera considérée, même > lors du rendu côté serveur. Le bloc `catch` peut être omis si vous n'avez pas besoin d'afficher quoi que ce soit lors que la promesse est rejetée (ou si aucune erreur n'est possible). ```svelte {#await promise}

    en attente de la résolution de la promesse...

    {:then value}

    La valeur vaut {value}

    {/await} ``` Si l'état d'attente ne vous intéresse pas, vous pouvez aussi ignorer le bloc initial. ```svelte {#await promise then value}

    La valeur vaut {value}

    {/await} ``` De même, si vous souhaitez uniquement afficher l'état d'erreur, vous pouvez ignorer le bloc `then`. ```svelte {#await promise catch error}

    Voici l'erreur : {error}

    {/await} ``` > [!NOTE] Vous pouvez utiliser `#await` avec > [`import(...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) > pour afficher des composants de manière différée : > > ```svelte > {#await import('./Component.svelte') then { default: Component }} > > {/await} > ``` # {#snippet ...} ```svelte {#snippet name()}...{/snippet} ``` ```svelte {#snippet name(param1, param2, paramN)}...{/snippet} ``` Les snippets, ainsi que les [balises de rendu (_render tags_)](@render) sont un moyen de créer des morceaux de markup réutilisables dans vos composants. Plutôt que d'écrire du code dupliqué comme [ceci](/playground/untitled#H4sIAAAAAAAAE5VUYW-kIBD9K8Tmsm2yXXRzvQ-s3eR-R-0HqqOQKhAZb9sz_vdDkV1t000vRmHewMx7w2AflbIGG7GnPlK8gYhFv42JthG-m9Gwf6BGcLbVXZuPSGrzVho8ZirDGpDIhldgySN5GpEMez9kaNuckY1ANJZRamRuu2ZnhEZt6a84pvs43mzD4pMsUDDi8DMkQFYCGdkvsJwblFq5uCik9bmJ4JZwUkv1eoknWigX2eGNN6aGXa6bjV8ybP-X7sM36T58SVcrIIV2xVIaA41xeD5kKqWXuqpUJEefOqVuOkL9DfBchGrzWfu0vb-RpTd3o-zBR045Ga3HfuE5BmJpKauuhbPtENlUF2sqR9jqpsPSxWsMrlngyj3VJiyYjJXb1-lMa7IWC-iSk2M5Zzh-SJjShe-siq5kpZRPs55BbSGU5YPyte4vVV_VfFXxVb10dSLf17pS2lM5HnpPxw4Zpv6x-F57p0jI3OKlVnhv5V9wPQrNYQQ9D_f6aGHlC89fq1Z3qmDkJCTCweOGF4VUFSPJvD_DhreVdA0eu8ehJJ5x91dBaBkpWm3ureCFPt3uzRv56d4kdp-2euG38XZ6dsnd3ZmPG9yRBCrzRUvi-MccOdwz3qE-fOZ7AwAhlrtTUx3c76vRhSwlFBHDtoPhefgHX3dM0PkEAAA=)... ```svelte {#each images as image} {#if image.href}
    {image.caption}
    {image.caption}
    {:else}
    {image.caption}
    {image.caption}
    {/if} {/each} ``` ... vous pouvez écrire [ceci](/playground/untitled#H4sIAAAAAAAAE5VUYW-bMBD9KxbRlERKY4jWfSA02n5H6QcXDmwVbMs-lnaI_z6D7TTt1moTAnPvzvfenQ_GpBEd2CS_HxPJekjy5IfWyS7BFz0b9id0CM62ajDVjBS2MkLjqZQldoBE9KwFS-7I_YyUOPqlRGuqnKw5orY5pVpUduj3mitUln5LU3pI0_UuBp9FjTwnDr9AHETLMSeHK6xiGoWSLi9yYT034cwSRjohn17zcQPNFTs8s153sK9Uv_Yh0-5_5d7-o9zbD-UqCaRWrllSYZQxLw_HUhb0ta-y4NnJUxfUvc7QuLJSaO0a3oh2MLBZat8u-wsPnXzKQvTtVVF34xK5d69ThFmHEQ4SpzeVRediTG8rjD5vBSeN3E5JyHh6R1DQK9-iml5kjzQUN_lSgVU8DhYLx7wwjSvRkMDvTjiwF4zM1kXZ7DlF1eN3A7IG85e-zRrYEjjm0FkI4Cc7Ripm0pHOChexhcWXzreeZyRMU6Mk3ljxC9w4QH-cQZ_b3T5pjHxk1VNr1CDrnJy5QDh6XLO6FrLNSRb2l9gz0wo3S6m7HErSgLsPGMHkpDZK31jOanXeHPQz-eruLHUP0z6yTbpbrn223V70uMXNSpQSZjpL0y8hcxxpNqA6_ql3BQAxlxvfpQ_uT9GrWjQC6iRHM8D0MP0GQsIi92QEAAA=) : ```svelte {#snippet figure(image)}
    {image.caption}
    {image.caption}
    {/snippet} {#each images as image} {#if image.href} {@render figure(image)} {:else} {@render figure(image)} {/if} {/each} ``` Comme avec les déclarations de fonctions, les snippets peuvent avoir un nombre arbitraire de paramètres, qui peuvent avoir des valeurs par défaut, et vous pouvez déstructurer chaque paramètre. Vous ne pouvez cependant pas utiliser de paramètre de reste. ## Portée de snippet [!VO]Snippet scope Les snippets peuvent être déclarés n'importe où dans votre composant. Ils peuvent référencer des valeurs déclarées en dehors de leur définition, par exemple dans une balise ` {#snippet hello(name)}

    salut {name} ! {message} !

    {/snippet} {@render hello('alice')} {@render hello('bob')} ``` ... et ils sont "visibles" par tout ce qui se trouve dans la même portée lexicale (c-à-d les balises soeurs, et les enfants de ces balises) : ```svelte
    {#snippet x()} {#snippet y()}...{/snippet} {@render y()} {/snippet} {@render y()}
    {@render x()} ``` Les snippets peuvent se référencer eux-mêmes et les uns les autres ([demo](/playground/untitled#H4sIAAAAAAAAE2WPTQqDMBCFrxLiRqH1Zysi7TlqF1YnENBJSGJLCYGeo5tesUeosfYH3c2bee_jjaWMd6BpfrAU6x5oTvdS0g01V-mFPkNnYNRaDKrxGxto5FKCIaeu1kYwFkauwsoUWtZYPh_3W5FMY4U2mb3egL9kIwY0rbhgiO-sDTgjSEqSTvIDs-jiOP7i_MHuFGAL6p9BtiSbOTl0GtzCuihqE87cqtyam6WRGz_vRcsZh5bmRg3gju4Fptq_kzQBAAA=)) : ```svelte {#snippet blastoff()} 🚀 {/snippet} {#snippet countdown(n)} {#if n > 0} {n}... {@render countdown(n - 1)} {:else} {@render blastoff()} {/if} {/snippet} {@render countdown(10)} ``` ## Passer des snippets aux composants [!VO]Passing snippets to components Au sein du template, les snippets sont des valeurs comme les autres. Ainsi, ils peuvent être passés aux composants en tant que props ([demo](/playground/untitled#H4sIAAAAAAAAE3VS247aMBD9lZGpBGwDASRegonaPvQL2qdlH5zYEKvBNvbQLbL875VzAcKyj3PmzJnLGU8UOwqSkd8KJdaCk4TsZS0cyV49wYuJuQiQpGd-N2bu_ooaI1YwJ57hpVYoFDqSEepKKw3mO7VDeTTaIvxiRS1gb_URxvO0ibrS8WanIrHUyiHs7Vmigy28RmyHHmKvDMbMmFq4cQInvGSwTsBYWYoMVhCSB2rBFFPsyl0uruTlR3JZCWvlTXl1Yy_mawiR_rbZKZrellJ-5JQ0RiBUgnFhJ9OGR7HKmwVoilXeIye8DOJGfYCgRlZ3iE876TBsZPX7hPdteO75PC4QaIo8vwNPePmANQ2fMeEFHrLD7rR1jTNkW986E8C3KwfwVr8HSHOSEBT_kGRozyIkn_zQveXDL3rIfPJHtUDwzShJd_Qk3gQCbOGLsdq4yfTRJopRuin3I7nv6kL7ARRjmLdBDG3uv1mhuLA3V2mKtqNEf_oCn8p9aN-WYqH5peP4kWBl1UwJzAEPT9U7K--0fRrrWnPTXpCm1_EVdXjpNmlA8G1hPPyM1fKgMqjFHjctXGjLhZ05w0qpDhksGrybuNEHtJnCalZWsuaTlfq6nPaaBSv_HKw-K57BjzOiVj9ZKQYKzQjZodYFqydYTRN4gPhVzTDO2xnma3HsVWjaLjT8nbfwHy7Q5f2dBAAA)) : ```svelte {#snippet header()} fruit qté prix total {/snippet} {#snippet row(d)} {d.name} {d.qty} {d.price} {d.qty * d.price} {/snippet} ``` On peut voir cette technique comme une façon de passer du contenu à un composant, plutôt que des données. Le concept est similaire à celui des slots pour les composants web. Pour simplifier l'écriture, les snippets déclarés directement _à l'intérieur_ d'un composant deviennent implicitement des props _sur_ le composant ([demo](/playground/untitled#H4sIAAAAAAAAE3VSTa_aMBD8Kyu_SkAbCA-JSzBR20N_QXt6vIMTO8SqsY29tI2s_PcqTiB8vaPHs7MzuxuIZgdBMvJLo0QlOElIJZXwJHsLBBvb_XUASc7Mb9Yu_B-hsMMK5sUzvDQahUZPMkJ96aTFfKd3KA_WOISfrFACKmcOMFmk8TWUTjY73RFLoz1C5U4SPWzhrcN2GKDrlcGEWauEnyRwxCaDdQLWyVJksII2uaMWTDPNLtzX5YX8-kgua-GcHJVXI3u5WEPb0d83O03TMZSmfRzOkG1Db7mNacOL19JagVALxoWbztq-H8U6j0SaYp2P2BGbOyQ2v8PQIFMXLKRDk177pq0zf6d8bMrzwBdd0pamyPMb-IjNEzS2f86Gz_Dwf-2F9nvNSUJQ_EOSoTuJNvngqK5v4Pas7n4-OCwlEEJcQTIMO-nSQwtb-GSdsX46e9gbRoP9yGQ11I0rEuycunu6PHx1QnPhxm3SFN15MOlYEFJZtf0dUywMbwZOeBGsrKNLYB54-1R9WNqVdki7usim6VmQphf7mnpshiQRhNAXdoOfMyX3OgMlKtz0cGEcF27uLSul3mewjPjgOOoDukxjPS9rqfh0pb-8zs6aBSt_7505aZ7B9xOi0T9YKW4UooVsr0zB1BTrWQJ3EL-oWcZ572GxFoezCk37QLe3897-B2i2U62uBAAA)) : ```svelte
    {#snippet header()} {/snippet} {#snippet row(d)} {/snippet}
    fruit qté prix total{d.name} {d.qty} {d.price} {d.qty * d.price}
    ``` Tout contenu à l'intérieur d'une balise de composant qui n'est pas une déclaration de snippet fait implicitement partie du snippet `children` ([demo](/playground/untitled#H4sIAAAAAAAAE3WOQQrCMBBFrzIMggql3ddY1Du4si5sOmIwnYRkFKX07lKqglqX8_7_w2uRDw1hjlsWI5ZqTPBoLEXMdy3K3fdZDzB5Ndfep_FKVnpWHSKNce1YiCVijirqYLwUJQOYxrsgsLmIOIZjcA1M02w4n-PpomSVvTclqyEutDX6DA2pZ7_ABIVugrmEC3XJH92P55_G39GodCmWBFrQJ2PrQAwdLGHig_NxNv9xrQa1dhWIawrv1Wzeqawa8953D-8QOmaEAQAA)) : ```svelte ``` ```svelte ``` > [!NOTE] Notez que vous ne pouvez pas avoir une prop appelée `children` si vous avez également du > contenu au sein du composant — pour cette raison, vous devriez éviter de définir des props avec ce > nom. Vous pouvez déclarer des props de snippet comme étant optionnelles. Vous pouvez soit utiliser le chaînage optionnel pour ne rien afficher du tout si le snippet n'est pas défini... ```svelte {@render children?.()} ``` ... soit utiliser un bloc `#if` pour afficher du contenu par défaut : ```svelte {#if children} {@render children()} {:else} contenu par défaut {/if} ``` ## Typer les snippets [!VO]Typing snippets Les snippets implémentent l'interface `Snippet` importée depuis `'svelte'` : ```svelte ``` Avec ce changement, des petits gribouillis rouges vont apparaître si vous essayez d'utiliser le composant sans fournir une prop `data` et un snippet `row`. Notez que le type d'argument fourni à `Snippet` est un tuple, puisque les snippets peuvent avoir plusieurs paramètres. Nous pouvons restreindre encore un peu le typage en déclarant un générique, de sorte que `data` et `row` soient toujours du même type : ```svelte ``` ## Exporter des snippets [!VO]Exporting snippets Les snippets déclarés à la racine d'un fichier `.svelte` peuvent être exportés depuis un ` {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` > [!NOTE] > Ceci nécessite Svelte 5.5.0 ou plus récent ## Snippets programmatiques [!VO]Programmatic snippets Les snippets peuvent être créés programmatiquement avec l'API [`createRawSnippet`](svelte#createRawSnippet). Cela ne concerne que des cas avancés. ## Snippets et slots [!VO]Snippets and slots En Svelte 4, du contenu peut être fourni aux composants en utilisant des [slots](legacy-slots). Les snippets sont plus puissants et plus polyvalents, de sorte que les slots sont dépréciés avec Svelte 5. # {@render ...} Pour afficher un [snippet](snippet), utiliser une balise `{@render ...}`. ```svelte {#snippet sum(a, b)}

    {a} + {b} = {a + b}

    {/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)} ``` L'expression peut être un identifiant comme `sum`, ou une expression JavaScript arbitraire : ```svelte {@render (cool ? snippetCool : snippetNul)()} ``` ## Snippets optionnels [!VO]Optional snippets Si le snippet est potentiellement `undefined` — par exemple parce que c'est une valeur pas encore définie — vous pouvez alors utiliser le chaînage optionnel pour ne l'afficher que lorsqu'il sera défini : ```svelte {@render children?.()} ``` Vous pouvez également utiliser un bloc [`{#if ...}`](if) avec une clause `:else` pour afficher du contenu par défaut : ```svelte {#if children} {@render children()} {:else}

    contenu par défaut

    {/if} ``` # {@html ...} Pour injecter du HTML brut dans vos composants, utilisez la balise `{@html ...}` : ```svelte
    {@html content}
    ``` > [!NOTE] Assurez-vous soit d'échapper la chaîne fournie, soit de ne fournir que des valeurs qui > sont sous votre contrôle pour votre protéger d'éventuelles attaques > [XSS](https://owasp.org/www-community/attacks/xss/). N'affichez jamais de contenu non nettoyé. L'expression doit être du HTML valide et autonome — le code suivant ne fonctionne pas, car `
    ` n'est pas du code HTML valide : ```svelte {@html '
    '}contenu{@html '
    '} ``` De plus, si vous fournissez du code Svelte, celui-ci ne sera pas compilé. ## Style [!VO]Styling Le contenu affiché de cette manière est "invisible" pour Svelte, et ne sera donc pas concerné par les [styles scopés](scoped-styles) — autrement dit, le code suivant ne fonctionnera pas, et les styles de `a` et `img` seront considérés comme non utilisés : ```svelte
    {@html content}
    ``` Utilisez plutôt le modificateur `:global` pour cibler tout ce qui se trouve dans l'`
    ` : ```svelte ``` # {@const ...} La balise `{@const ...}` définit une constante locale. ```svelte {#each boxes as box} {@const area = box.width * box.height} {box.width} * {box.height} = {area} {/each} ``` L'usage de `{@const}` est uniquement autorisé immédiatement en enfant d'un bloc — `{#if ...}`, `{#each ...}`, `{#snippet ...}`, etc. — d'un ``, ou d'une ``. # {@debug ...} La balise `{@debug ...}` offre une alternative à `console.log(...)`. Elle permet de logger les valeurs de variables spécifiques lorsqu'elles changent, et met en pause l'exécution si vous avez les outils de développement ouverts. ```svelte {@debug user}

    Coucou {user.firstname} !

    ``` `{@debug ...}` attend une liste de noms de variables séparés par des virgules (mais pas d'expressions arbitraires). ```svelte {@debug user} {@debug user1, user2, user3} {@debug user.firstname} {@debug myArray[0]} {@debug !isReady} {@debug typeof user === 'object'} ``` La balise `{@debug}` utilisée sans aucun argument va ajouter une déclaration `debugger` qui sera déclenchée lorsque _n'importe_ quel état change, plutôt que celui de variables spécifiques. # bind: D"ordinaire, les données circulent vers le bas, du parent vers ses enfants. La directive `bind:` permet de faire circuler les données dans l'autre sens, de l'enfant vers le parent. La syntaxe générale est `bind:property={expression}`, où `expression` est une _lvalue_ (c-à-d une variable ou une propriété d'objet). Lorsque l'expression est un identifiant du même nom que la propriété, il est possible d'omettre l'expression — autrement dit ces deux écritures sont équivalentes : ```svelte ``` Svelte crée un gestionnaire d'évènement qui met à jour la valeur liée. Si un élément a déjà un gestionnaire pour le même évènement, ce gestionnaire sera déclenché avant que la valeur liée soit mise à jour. La plupart des liaisons sont à _double sens_ (_two-way_), ce qui signifie que toute modification de la valeur va impacter l'élément est vice-versa. Quelques liaisons sont en _lecture seule_ (_readonly_), ce qui signifie que les changements de valeur n'auront aucun effet sur l'élément. ## Liaisons de fonction [!VO]Function bindings Vous pouvez aussi utiliser `bind:property={get, set}`, où `get` et `set` sont des fonctions, vous permettant d'effectuer des validations et des transformations : ```svelte value, (v) => value = v.toLowerCase()} /> ``` Dans le cas de liaisons en lecture seule comme [dimension bindings](#Dimensions), la valeur `get` doit être `null` : ```svelte
    ...
    ``` > [!NOTE] > Les liaisons de fonctions sont disponible à partir de Svelte version 5.9.0. ## `` Une directive `bind:value` sur un élément `` crée une liaison avec la propriété `value` de l'input : ```svelte

    {message}

    ``` Dans le cas d'un input numérique (`type="number"` ou `type="range"`), la valeur sera transformée en nombre ([démo](/playground/untitled#H4sIAAAAAAAAE6WPwYoCMQxAfyWEPeyiOOqx2w74Hds9pBql0IllmhGXYf5dKqwiyILsLXnwwsuI-5i4oPkaUX8yo7kCnKNQV7dNzoty4qSVBSr8jG-Poixa0KAt2z5mbb14TaxA4OCtKCm_rz4-f2m403WltrlrYhMFTtcLNkoeFGqZ8yhDF7j3CCHKzpwoDexGmqCL4jwuPUJHZ-dxVcfmyYGe5MAv-La5pbxYFf5Z9Zf_UJXb-sEMquFgJJhBmGyTW5yj8lnRaD_w9D1dAKSSj7zqAQAA)) : ```svelte

    {a} + {b} = {a + b}

    ``` Si l'input est vide ou invalide (dans le cas de `type="number"`), la valeur sera `undefined`. Depuis la version 5.6.0, si un `` faisant partie d'un formulaire possède une valeur par défaut `defaultValue`, il récupèrera cette valeur par défaut plutôt que la chaîne de caractères vide lors de la réinitialisation du formulaire. Notez que pour le rendu initial, la valeur de la liaison est prioritaire sauf s'il cette valeur est `null` ou `undefined`. ```svelte
    ``` > [!NOTE] > Utilisez les boutons de réinitialisation avec prudence, et assurez-vous que les utilisateurs et > utilisatrices ne cliquent pas dessus accidentellement lorsqu'ils souhaitent soumettre le > formulaire. ## `` Les inputs de type checkbox et radio peuvent être liés avec `bind:checked` : ```svelte ``` Depuis la version 5.6.0, si un `` faisant partie d'un formulaire possède une valeur par défaut `defaultChecked`, il récupèrera cette valeur par défaut plutôt que `false` lors de la réinitialisation du formulaire. Notez que pour le rendu initial, la valeur de la liaison est prioritaire sauf s'il cette valeur est `null` ou `undefined`. ```svelte
    ``` ## `` Les inputs qui fonctionnent en groupe peuvent utiliser `bind:group`. ```svelte ``` > [!NOTE] `bind:group` ne fonctionne que si les inputs sont dans le même composant Svelte. ## `` Vous pouvez utiliser `bind:files` sur les éléments `` de `type="file"` pour obtenir une [`FileList` des fichiers sélectionnés](https://developer.mozilla.org/fr/docs/Web/API/FileList). Lorsque vous souhaitez mettre à jour les fichiers programmatiquement, vous pouvez toujours utiliser un objet `FileList`. Actuellement les objets `FileList` ne peuvent pas être construits directement, vous aurez besoin de d'abord créer un nouvel objet [`DataTransfer`](https://developer.mozilla.org/fr/docs/Web/API/DataTransfer) et en extraire les `files`. ```svelte ``` Les objets `FileList` ne peuvent pas non plus être modifiés. Si vous souhaitez par ex. supprimer un fichier de la liste, vous devez créer un nouvel objet `DataTransfer` et y ajouter uniquement les fichiers que vous souhaitez garder. > [!NOTE] `DataTransfer` peut ne pas être disponible dans certains runtimes JS de serveur. Ne pas > initialiser l'état lié aux `files` permet d'éviter de potentielles erreurs si les composants sont > générés côté serveur. ## `` correspond à la propriété `value` de l'` ``` Lorsque la valeur d'une ` ``` ## `