This is the developer documentation for Svelte. # 概要 Svelte は Web 上のユーザーインターフェースを構築するためのフレームワークです。Svelte はコンパイラを使用し、HTML、CSS、JavaScript で記述された宣言的なコンポーネントを... ```svelte ``` ...無駄のない、タイトで最適化された JavaScript に変換します。 これにより、スタンドアローンなコンポーネントからフルスタックアプリ (Svelte のアプリケーションフレームワークである [SvelteKit](../kit) を使用) まで、お望みのものをなんでも構築することができます。 こちらのページはリファレンスドキュメントとして提供されています。もしあなたが Svelte の初心者なら、先に[インタラクティブなチュートリアル](/tutorial)から始めて、わからないことがあるときにこちらに戻ってくることをおすすめします。 また、[Playground](/playground) を使ってオンラインで Svelte を試すこともできますし、より高機能な環境が必要なら [StackBlitz](https://sveltekit.new) で試すこともできます。 # Getting started [SvelteKit](../kit) をお使いいただくことをおすすめします。[ほとんどの用途](../kit/project-types)でお使いいただけます。これは Svelte チームによるオフィシャルなアプリケーションフレームワークで、[Vite](https://vite.dev/)を活用しています。新しいプロジェクトを作成するには: ```bash npx sv create myapp cd myapp npm install npm run dev ``` まだ Svelte についてよく知らなくても心配いりません! SvelteKit が提供する便利な機能等は一旦無視して、後から学び始めても問題ありません。 ## SvelteKit の代替手段 Svelteを直接Viteで使用することもできます。その場合、`npm create vite@latest` を実行し、`svelte` オプションを選択します。この方法では、`npm run build` を実行すると、[vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) を使用して、`dist` ディレクトリ内に HTML、JS、CSSファイルが生成されます。ほとんどの場合、[ルーティングライブラリ](faq#Is-there-a-router)を選択する必要があるでしょう。 >[!NOTE] Vite は [single page apps (SPA)](../kit/glossary#SPA) をビルドするためよくスタンドアロンモードで使用されますが、[SPA は SvelteKit でも構築できます](../kit/single-page-apps)。 また、[Rollup](https://github.com/sveltejs/rollup-plugin-svelte)、[Webpack](https://github.com/sveltejs/svelte-loader)、[その他いくつかのプラグイン](https://sveltesociety.dev/packages?category=build-plugins)もありますが、Viteをお勧めします。 ## エディタツール Svelteチームは、[VS Code 拡張機能](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode)を提供しています。また、様々な[他のエディター](https://sveltesociety.dev/resources#editor-support)やツールとの統合も利用可能です。 さらに、[sv check](https://github.com/sveltejs/cli) を使ってコマンドラインからコードをチェックすることもできます。 ## サポートを受ける [Discord チャットルーム](/chat)で気軽に質問してください!また、[Stack Overflow](https://stackoverflow.com/questions/tagged/svelte) でも回答を見つけることができます。 # .svelte ファイル コンポーネントは Svelte アプリケーションの構成要素です。これらは `.svelte` ファイルに書かれ、HTML のスーパーセットを使って記述されます。 以下の3つのセクション — script, styles, markup — は任意です。 ```svelte /// file: MyComponent.svelte ``` ## ` ``` このブロックから `export` バインディングを使用してエクスポートすることができ、それらはコンパイルされたモジュールのエクスポートとして扱われます。ただし、コンポーネント自体にデフォルトエクスポートがされるため `export default` は使用できません。 > [!NOTE] TypeScriptを使用していて、`module` ブロックからエクスポートされたものを `.ts` ファイルにインポートする場合は、TypeScriptがそれらを認識できるようにエディタの設定を行う必要があります。VS Code拡張機能やIntelliJプラグインを使用している場合はこの設定が必要となりますが、それ以外の場合は [TypeScript エディタープラグイン](https://www.npmjs.com/package/typescript-svelte-plugin) を設定する必要がある場合があります。 > [!LEGACY] > Svelte 4 では、このスクリプトタグは ` ``` (もしかしたらあなたが使用したことがあるかもしれない) 他のフレームワークとは違い、state を操作するための API はありません — `count` はオブジェクトや関数ではなくただの number であり、他の変数を更新するのと同じように更新することができます。 ### Deep state もし `$state` を配列やシンプルなオブジェクトで使用した場合、リアクティブが深い (原文: deeply reactive) _state proxy_ になります。[proxy](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy) によって Svelte はプロパティが読み書き (`array.push(...)` のようなメソッド経由で行われたものを含む) されたときにコードを実行でき、きめ細やかな更新 (原文: granular updates) をトリガーすることができます。 state は、Svelte が配列やシンプルなオブジェクト(classなど)以外のものを見つけるまで再帰的に proxy 化 されます。このような場合... ```js let todos = $state([ { done: false, text: 'add more todos' } ]); ``` ...個々の todo のプロパティが変更されると、UI の中の、その変更されたプロパティに依存する部分に対して更新がトリガーされます: ```js let todos = [{ done: false, text: 'add more todos' }]; // ---cut--- todos[0].done = !todos[0].done; ``` 配列に新たなオブジェクトを push すると、それも proxy 化されます。 ```js let todos = [{ done: false, text: 'add more todos' }]; // ---cut--- todos.push({ done: false, text: 'eat lunch' }); ``` > [!NOTE] proxy のプロパティを更新しても、元のオブジェクトは変更されません。 もしリアクティブな値を分割した場合、その参照はリアクティブではありません — 通常の JavaScript と同じように、分割時点で評価されます: ```js let todos = [{ done: false, text: 'add more todos' }]; // ---cut--- let { done, text } = todos[0]; // this will not affect the value of `done` todos[0].done = !todos[0].done; ``` ### Classes class インスタンスは proxy されません。その代わりに、class のフィールド (public か private かを問わず) にも `$state` を使用するか、または `constructor` の内側で最初に代入するときに `$state` を使用することができます: ```js // @errors: 7006 2554 class Todo { done = $state(false); constructor(text) { this.text = $state(text); } reset() { this.text = ''; this.done = false; } } ``` > [!NOTE] コンパイラは `done` と `text` を、プライベートなフィールドを参照する class prototype の `get`/`set` メソッドに変換します。これは、プロパティが enumerable ではないことを意味します。 JavaScript でメソッドを呼び出すとき、[`this`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this) の値が問題になります。以下のコードは動作しません、なぜなら `reset` メソッドの中にある `this` が `Todo` ではなく ` ``` インライン関数を使うこともできますし... ```svelte ``` ...class の定義でアロー関数を使うこともできます: ```js // @errors: 7006 2554 class Todo { done = $state(false); constructor(text) { this.text = $state(text); } +++reset = () => {+++ this.text = ''; this.done = false; } } ``` > Svelte provides reactive implementations of built-in classes like `Set` and `Map` that can be imported from [`svelte/reactivity`](svelte-reactivity). ## `$state.raw` オブジェクトや配列を、深いリアクティブ (deeply reactive) にしたくない場合は、`$state.raw` を使用します。 `$state.raw` で宣言された state は変更できません、再代入のみ可能です。言い換えると、もし更新したいのであれば、オブジェクトのプロパティに代入したり配列のメソッドの `push` などを使用するのではなく、オブジェクトや配列を丸ごと置き換えてください。 ```js let person = $state.raw({ name: 'Heraclitus', age: 49 }); // this will have no effect person.age += 1; // this will work, because we're creating a new person person = { name: 'Heraclitus', age: 50 }; ``` 変更する予定がない大きい配列やオブジェクトでこれを使用すると、パフォーマンスを改善することができます。リアクティブにするためのコストを避けられるからです。raw state には、リアクティブな state を含められることにご注意ください (例えば、リアクティブなオブジェクトの配列 (原文: a raw array of reactive objects))。 As with `$state`, you can declare class fields using `$state.raw`. ## `$state.snapshot` 深いリアクティブ (deeply reactive) な `$state` proxy の静的なスナップショットを取得するには、`$state.snapshot` を使用します: ```svelte ``` これは、例えば `structuredClone` のような proxy を受け付けない外部のライブラリや API に state を渡したいときに便利です。 ## 関数に state を渡す JavaScript は _値渡し_ の言語です — 関数を呼び出すとき、その引数は _変数_ ではなく _値_ です。言い換えると: ```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); // still 3! ``` もし `add` が `a` と `b` の現在の値にアクセスし、`total` の現在の値を返したいのであれば、代わりに関数を使う必要があります: ```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 ``` Svelte の state も同様です — `$state` rune で宣言されたものを参照するとき... ```js let a = +++$state(1)+++; let b = +++$state(2)+++; ``` ...その現在の値にアクセスします。 '関数(function)' は意味が広範囲にわたることにご注意ください — proxy のプロパティや [`get`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/get)/[`set`](https://developer.mozilla.org/ja/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 ``` ...もしこのようなコードを書いている場合は、代わりに [class](#Classes) を使用することをご検討ください。 ## モジュール間で state を渡す `.svelte.js` や `.svelte.ts` ファイルでは state を宣言できますが、その state は直接再代入されていない場合に限り、エクスポートすることができます。言い換えると、以下のようなことはできないということです: ```js /// file: state.svelte.js export let count = $state(0); export function increment() { count += 1; } ``` その理由は、`count` に対するすべての参照は Svelte コンパイラによって変換されるからです — 上記のコードは大雑把に言えば以下と同じです: ```js /// file: state.svelte.js (compiler output) // @filename: index.ts interface Signal { value: T; } interface Svelte { state(value?: T): Signal; get(source: Signal): T; set(source: Signal, value: T): void; } declare const $: Svelte; // ---cut--- export let count = $.state(0); export function increment() { $.set(count, $.get(count) + 1); } ``` > [!NOTE] Svelte が生成するコードは [playground](/playground) で 'JS Output' タブをクリックすると見ることができます。 Svelte のコンパイラは一度に1つのファイルのみ処理するため、もし別のファイルが `count` をインポートしている場合、Svelte はそれぞれの参照を `$.get` や `$.set` でラップする必要があるかどうかがわかりません: ```js // @filename: state.svelte.js export let count = 0; // @filename: index.js // ---cut--- import { count } from './state.svelte.js'; console.log(typeof count); // 'object', not 'number' ``` そのため、モジュール間で state を共有するには、2つの方法があります。1つ目は再代入をしないことです... ```js // This is allowed — since we're updating // `counter.count` rather than `counter`, // Svelte doesn't wrap it in `$.state` export const counter = $state({ count: 0 }); export function increment() { counter.count += 1; } ``` ...2つ目は、直接エクスポートしないことです: ```js let count = $state(0); export function getCount() { return count; } export function increment() { count += 1; } ``` # $derived derived state は `$derived` rune を使用して宣言します: > [!NOTE] 日本語翻訳 TIPS:「derive」は「引き出す」「派生する」「由来する」などの意。「derived state」は、他の state を元に計算される state を意味します。 ```svelte

{count} doubled is {doubled}

``` `$derived(...)` 内の式は副作用(side-effects)がないものでなければなりません。Svelte は derived の式の中での state の変更 (例: `count++`) を許可しません。 `$state` と同様に、class のフィールドを `$derived` としてマークすることができます。 > [!NOTE] Svelte コンポーネント内のコードは作成時に一度だけ実行されます。`$derived` rune がない場合、`count` が変化しても `doubled` は元の値を維持します。 ## `$derived.by` 短い式に収まらない複雑な derived を作成する必要がある場合があります。その場合は、引数として関数を受け取る `$derived.by` を使用できます。 ```svelte ``` 本質的に、`$derived(expression)` は `$derived.by(() => expression)` と同等です。 ## 依存関係を理解する `$derived` 式 (または `$derived.by` の関数本体) 内で同期的に読み取られるものはすべて、derived state の _依存関係(dependency)_ と見なされます。その state が変更されると、derived は _dirty_ としてマークされ、次回読み取られる際に再計算されます。 state の一部を依存関係として扱わないようにするには、[`untrack`](svelte#untrack) を使用します。 ## derived の値を上書きする derived の式はその依存が変化したときに再計算されますが、再代入することによって一時的に値を上書きすることができます (`const` で宣言されていない場合に限る)。これは例えば楽観的 UI のように、その値が '単一の情報源(source of truth)' (例えばサーバーからのデータ) から計算されるが、ユーザーにすぐにフィードバックを表示したい場合に便利です: ```svelte ``` > [!NOTE] Svelte 5.25 以前は、derived は読取専用でした。 ## derived とリアクティビティ `$state` はオブジェクトや配列を[深いリアクティブな proxy (deeply reactive proxies)]($state#Deep-state) に変換しますが、`$derived` の値はそれがそのまま残ります (as-is) 。[例えばこのようなケースでは](/playground/untitled#H4sIAAAAAAAAE4VU22rjMBD9lUHd3aaQi9PdstS1A3t5XvpQ2Ic4D7I1iUUV2UjjNMX431eS7TRdSosxgjMzZ45mjt0yzffIYibvy0ojFJWqDKCQVBk2ZVup0LJ43TJ6rn2aBxw-FP2o67k9oCKP5dziW3hRaUJNjoYltjCyplWmM1JIIAn3FlL4ZIkTTtYez6jtj4w8WwyXv9GiIXiQxLVs9pfTMR7EuoSLIuLFbX7Z4930bZo_nBrD1bs834tlfvsBz9_SyX6PZXu9XaL4gOWn4sXjeyzftv4ZWfyxubpzxzg6LfD4MrooxELEosKCUPigQCMPKCZh0OtQE1iSxcsmdHuBvCiHZXALLXiN08EL3RRkaJ_kDVGle0HcSD5TPEeVtj67O4Nrg9aiSNtBY5oODJkrL5QsHtN2cgXp6nSJMWzpWWGasdlsGEMbzi5jPr5KFr0Ep7pdeM2-TCelCddIhDxAobi1jqF3cMaC1RKp64bAW9iFAmXGIHfd4wNXDabtOLN53w8W53VvJoZLh7xk4Rr3CoL-UNoLhWHrT1JQGcM17u96oES5K-kc2XOzkzqGCKL5De79OUTyyrg1zgwXsrEx3ESfx4Bz0M5UjVMHB24mw9SuXtXFoN13fYKOM1tyUT3FbvbWmSWCZX2Er-41u5xPoml45svRahl9Wb9aasbINJixDZwcPTbyTLZSUsAvrg_cPuCR7s782_WU8343Y72Qtlb8OYatwuOQvuN13M_hJKNfxann1v1U_B1KZ_D_mzhzhz24fw85CSz2irtN9w9HshBK7AQAAA==)... ```svelte let items = $state([...]); let index = $state(0); let selected = $derived(items[index]); ``` ...`selected` のプロパティを変更 (または `selected` に `bind:`) すると、そのもとにある `items` 配列に影響します。もし `items` が深いリアクティブ(deeply reactive)でないなら、`selected` に対する変更は影響しません。 ## 更新の伝搬 Svelte は _push-pull reactivity_ と呼ばれる仕組みを使用しています — state が更新されると、それに依存するすべてのもの (直接的または間接的であるかを問わず) に即座に変更が通知されますが ('push')、derived の値は実際に読み取られるまで再評価されません ('pull')。 derived の新しい値が以前の値と参照的に同一である場合、下流の更新はスキップされます。つまり、`large` が変更されたときのみ、ボタン内のテキストが更新され、`count` が変更されても更新されません (たとえ `large` が `count` に依存していたとしても): ```svelte ``` # $effect Effects are functions that run when state updates, and can be used for things like calling third-party libraries, drawing on `` elements, or making network requests. They only run in the browser, not during server-side rendering. Generally speaking, you should _not_ update state inside effects, as it will make code more convoluted and will often lead to never-ending update cycles. If you find yourself doing so, see [when not to use `$effect`](#When-not-to-use-$effect) to learn about alternative approaches. You can create an effect with the `$effect` rune ([demo](/playground/untitled#H4sIAAAAAAAAE31S246bMBD9lZF3pSRSAqTVvrCAVPUP2sdSKY4ZwJJjkD0hSVH-vbINuWxXfQH5zMyZc2ZmZLVUaFn6a2R06ZGlHmBrpvnBvb71fWQHVOSwPbf4GS46TajJspRlVhjZU1HqkhQSWPkHIYdXS5xw-Zas3ueI6FRn7qHFS11_xSRZhIxbFtcDtw7SJb1iXaOg5XIFeQGjzyPRaevYNOGZIJ8qogbpe8CWiy_VzEpTXiQUcvPDkSVrSNZz1UlW1N5eLcqmpdXUvaQ4BmqlhZNUCgxuzFHDqUWNAxrYeUM76AzsnOsdiJbrBp_71lKpn3RRbii-4P3f-IMsRxS-wcDV_bL4PmSdBa2wl7pKnbp8DMgVvJm8ZNskKRkEM_OzyOKQFkgqOYBQ3Nq89Ns0nbIl81vMFN-jKoLMTOr-SOBOJS-Z8f5Y6D1wdcR8dFqvEBdetK-PHwj-z-cH8oHPY54wRJ8Ys7iSQ3Bg3VA9azQbmC9k35kKzYa6PoVtfwbbKVnBixBiGn7Pq0rqJoUtHiCZwAM3jdTPWCVtr_glhVrhecIa3vuksJ_b7TqFs4DPyriSjd5IwoNNQaAmNI-ESfR2p8zimzvN1swdCkvJHPH6-_oX8o1SgcIDAAA=)): ```svelte ``` When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed (unless accessed inside [`untrack`](svelte#untrack)), and re-runs the function when that state later changes. > [!NOTE] If you're having difficulty understanding why your `$effect` is rerunning or is not running see [understanding dependencies](#Understanding-dependencies). Effects are triggered differently than the `$:` blocks you may be used to if coming from Svelte 4. ### Understanding lifecycle Your effects run after the component has been mounted to the DOM, and in a [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) after state changes. 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. You can use `$effect` anywhere, not just at the top level of a component, as long as it is called while a parent effect is running. > [!NOTE] Svelte uses effects internally to represent logic and expressions in your template — this is how `

hello {name}!

` updates when `name` changes. An effect can return a _teardown function_ which will run immediately before the effect re-runs ([demo](/playground/untitled#H4sIAAAAAAAAE42SQVODMBCF_8pOxkPRKq3HCsx49K4n64xpskjGkDDJ0tph-O8uINo6HjxB3u7HvrehE07WKDbiyZEhi1osRWksRrF57gQdm6E2CKx_dd43zU3co6VB28mIf-nKO0JH_BmRRRVMQ8XWbXkAgfKtI8jhIpIkXKySu7lSG2tNRGZ1_GlYr1ZTD3ddYFmiosUigbyAbpC2lKbwWJkIB8ZhhxBQBWRSw6FCh3sM8GrYTthL-wqqku4N44TyqEgwF3lmRHr4Op0PGXoH31c5rO8mqV-eOZ49bikgtcHBL55tmhIkEMqg_cFB2TpFxjtg703we6NRL8HQFCS07oSUCZi6Rm04lz1yytIHBKoQpo1w6Gsm4gmyS8b8Y5PydeMdX8gwS2Ok4I-ov5NZtvQde95GMsccn_1wzNKfu3RZtS66cSl9lvL7qO1aIk7knbJGvefdtIOzi73M4bYvovUHDFk6AcX_0HRESxnpBOW_jfCDxIZCi_1L_wm4xGQ60wIAAA==)). ```svelte

{count}

``` Teardown functions also run when the effect is destroyed, which happens when its parent is destroyed (for example, a component is unmounted) or the parent effect re-runs. ### 依存関係を理解する `$effect` automatically picks up any reactive values (`$state`, `$derived`, `$props`) that are _synchronously_ read inside its function body (including indirectly, via function calls) and registers them as dependencies. When those dependencies change, the `$effect` schedules a re-run. If `$state` and `$derived` are used directly inside the `$effect` (for example, during creation of a [reactive class](https://svelte.dev/docs/svelte/$state#Classes)), those values will _not_ be treated as dependencies. 非同期的に読み取られる値 (例えば、`await` の後や `setTimeout` 内) は追跡されません。この例では、`color` が変更されると canvas が再描画されますが、`size` が変更されても再描画されません ([デモ](/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); // これは `color` が変更されるたびに再実行されます... context.fillStyle = color; setTimeout(() => { // ...しかしこれは `size` が変更されても再実行されません context.fillRect(0, 0, size, size); }, 0); }); ``` effect は、読み取るオブジェクトそのものが変更された場合にのみ再実行され、その中のプロパティが変更された場合には再実行されません。(オブジェクト内部の変更を開発時に観察したい場合は、[`$inspect`]($inspect) を使用できます。) ```svelte

{state.value} doubled is {derived.value}

``` effect は、前回実行されたときに読み取られた値のみに依存します。これは、条件付きコードを持つ effect にとって興味深い含意があります。 例えば、以下のコードスニペットで `condition` が `true` の場合、`if` ブロック内のコードが実行され、`color` が評価されます。そのため、`condition` または `color` の変更が [effect を再実行を引き起こします](/playground/untitled#H4sIAAAAAAAAE21RQW6DMBD8ytaNBJHaJFLViwNIVZ8RcnBgXVk1xsILTYT4e20TQg89IOPZ2fHM7siMaJBx9tmaWpFqjQNlAKXEihx7YVJpdIyfRkY3G4gB8Pi97cPanRtQU8AuwuF_eNUaQuPlOMtc1SlLRWlKUo1tOwJflUikQHZtA0klzCDc64Imx0ANn8bInV1CDhtHgjClrsftcSXotluLybOUb3g4JJHhOZs5WZpuIS9gjNqkJKQP5e2ClrR4SMdZ13E4xZ8zTPOTJU2A2uE_PQ9COCI926_hTVarIU4hu_REPlBrKq2q73ycrf1N-vS4TMUsulaVg3EtR8H9rFgsg8uUsT1B2F9eshigZHBRpuaD0D3mY8Qm2BfB5N2YyRzdNEYVDy0Ja-WsFjcOUuP1HvFLWA6H3XuHTUSmmDV2--0TXonxsKbp7G9C6R__NONS-MFNvxj_d6mBAgAA)。 一方で、`condition` が `false` の場合、`color` は評価されず、 effect は `condition` が変更されたときに _のみ_ 再実行されます。 ```ts // @filename: ambient.d.ts declare module 'canvas-confetti' { interface ConfettiOptions { colors: string[]; } function confetti(opts?: ConfettiOptions): void; export default confetti; } // @filename: index.js // ---cut--- import confetti from 'canvas-confetti'; let condition = $state(true); let color = $state('#ff3e00'); $effect(() => { if (condition) { confetti({ colors: [color] }); } else { confetti(); } }); ``` ## `$effect.pre` 稀なケースでは、DOM 更新の _前に_ コードを実行する必要がある場合があります。そのためには `$effect.pre` rune を使用できます: ```svelte
{#each messages as message}

{message}

{/each}
``` タイミングを除けば、`$effect.pre` は `$effect` とまったく同じように機能します。 ## `$effect.tracking` `$effect.tracking` rune は高度な機能で、コードが effect やテンプレートなどの tracking context の中でで実行されているかどうかを示します ([デモ](/playground/untitled#H4sIAAAAAAAACn3PwYrCMBDG8VeZDYIt2PYeY8Dn2HrIhqkU08nQjItS-u6buAt7UDzmz8ePyaKGMWBS-nNRcmdU-hHUTpGbyuvI3KZvDFLal0v4qvtIgiSZUSb5eWSxPfWSc4oB2xDP1XYk8HHiSHkICeXKeruDDQ4Demlldv4y0rmq6z10HQwuJMxGVv4mVVXDwcJS0jP9u3knynwtoKz1vifT_Z9Jhm0WBCcOTlDD8kyspmML5qNpHg40jc3fFryJ0iWsp_UHgz3180oBAAA=)): ```svelte

in template: {$effect.tracking()}

``` これは、[`createSubscriber`](/docs/svelte/svelte-reactivity#createSubscriber) のような抽象化を実装するために使用されます。これにより、リアクティブな値を更新するリスナーが作成されますが、それらの値が追跡されている場合に _のみ_ 実行されます (例えば、イベントハンドラー内で読み取られる場合は除きます)。 ## `$effect.root` `$effect.root` rune は高度な機能で、自動クリーンアップされない非トラッキングスコープ (non-tracked scope) を作成します。これは、手動で制御したいネストされた effect に便利です。また、この rune は、コンポーネント初期化フェーズの外部で effect を作成することも可能にします。 ```js const destroy = $effect.root(() => { $effect(() => { // setup }); return () => { // cleanup }; }); // later... destroy(); ``` ## `$effect` を使うべきでないとき 一般的に、`$effect` は脱出口 (エスケープハッチ) のようなものと考えるのが最善です。たとえば、アナリティクス や直接的な DOM 操作などに便利ですが、頻繁に使用するツールではありません。特に、state を同期するために使用するのは避けてください。このように使用するのではなく... ```svelte ``` ...このようにしてください: ```svelte ``` > [!NOTE] `count * 2` のような単純な式よりも複雑なものの場合は、`$derived.by` を使用することもできます。 (例えば楽観的 UI を作るために) derived な値に再代入するために effect を使用しているなら、Svelte 5.25 からは [derived を直接オーバーライドできる]($derived#Overriding-derived-values) ようになったことにご留意ください。 effect を使ってある値を別の値に関連付けるような複雑な処理をしたくなるかもしれません。次の例は、「支出金額(money spent)」と「残高(money left)」という2つの入力が互いに連動していることを示しています。一方を更新すると、もう一方もそれに応じて更新されるべきです。このようなケースで effect を使用しないでください ([デモ](/playground/untitled#H4sIAAAAAAAAE5WRTWrDMBCFryKGLBJoY3fRjWIHeoiu6i6UZBwEY0VE49TB-O6VxrFTSih0qe_Ne_OjHpxpEDS8O7ZMeIAnqC1hAP3RA1990hKI_Fb55v06XJA4sZ0J-IjvT47RcYyBIuzP1vO2chVHHFjxiQ2pUr3k-SZRQlbBx_LIFoEN4zJfzQph_UMQr4hRXmBd456Xy5Uqt6pPKHmkfmzyPAZL2PCnbRpg8qWYu63I7lu4gswOSRYqrPNt3CgeqqzgbNwRK1A76w76YqjFspfcQTWmK3vJHlQm1puSTVSeqdOc_r9GaeCHfUSY26TXry6Br4RSK3C6yMEGT-aqVU3YbUZ2NF6rfP2KzXgbuYzY46czdgyazy0On_FlLH3F-UDXhgIO35UGlA1rAgAA)): ```svelte ``` 代わりに、可能な場合は `oninput` コールバック か — better still — [function bindings](bind#Function-bindings) を使用してください ([デモ](/playground/untitled#H4sIAAAAAAAAE5VRvW7CMBB-FcvqECQK6dDFJEgsnfoGTQdDLsjSxVjxhYKivHvPBwFUsXS8774_nwftbQva6I_e78gdvNo6Xzu_j3quG4cQtfkaNJ1DIiWA8atkE8IiHgEpYVsb4Rm-O3gCT2yji7jrXKB15StiOJKiA1lUpXrL81VCEUjFwHTGXiJZgiyf3TYIjSxq6NwR6uyifr0ohMbEZnpHH2rWf7ImS8KZGtK6osl_UqelRIyVL5b3ir5AuwWUtoXzoee6fIWy0p31e6i0XMocLfZQDuI6qtaeykGcR7UU6XWznFAZU9LN_X9B2UyVayk9f3ji0-REugen6U9upDOCcAWcLlS7GNCejWoQTqsLtrfBqHzxDu3DrUTOf0xwIm2o62H85sk6_OHG2jQWI4y_3byXXGMCAAA=)): ```svelte ``` どうしても effect 内で `$state` を更新する必要があり、同じ `$state` を読み書きすることで無限ループに陥った場合は、[untrack](svelte#untrack) を使用してください。 # $props コンポーネントへの入力は _props_ (プロパティの省略形) と呼ばれます。属性を要素に渡すのと同じように、props をコンポーネントに渡します: ```svelte ``` それに対し、`MyComponent.svelte` の内部では、`$props` rune を使用して props を受け取ることができます... ```svelte

this component is {props.adjective}

``` ...ただし、一般的には props を [_分割代入_](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) することが多いです: ```svelte

this component is {+++adjective+++}

``` ## Fallback values 分割代入を使用するとフォールバック値を宣言できます。これは親コンポーネントが特定の props を設定しない場合に使用されます (フォールバック値がなく、親コンポーネントから設定されない場合、その値は `undefined` になります): ```js let { adjective = 'happy' } = $props(); ``` > [!NOTE] フォールバック値はリアクティブな state proxy には変換されません ([Updating props](#Updating-props) を参照してください) ## Renaming props 分割代入を使用して props をリネームすることもできます。これは元の props の名前が無効な識別子や `super` のような JavaScript キーワードである場合に必要となります: ```js let { super: trouper = 'lights are gonna find me' } = $props(); ``` ## Rest props 最後に、_rest property_ を使用して、他のすべての props を取得できます: ```js let { a, b, c, ...others } = $props(); ``` ## Updating props コンポーネント内の props に対する参照は、その props 自体が更新されると更新されます — `App.svelte` の `count` が変更されると、それは `Child.svelte` 内でも変更されます。ただし、子コンポーネントは一時的に prop の値を上書きすることができ、これは保存されない一時的な state として便利です ([demo](/playground/untitled#H4sIAAAAAAAAE6WQ0WrDMAxFf0WIQR0Wmu3VTQJln7HsIfVcZubIxlbGRvC_DzuBraN92qPula50tODZWB1RPi_IX16jLALWSOOUq6P3-_ihLWftNEZ9TVeOWBNHlNhGFYznfqCBzeRdYHh6M_YVzsFNsNs3pdpGd4eBcqPVDMrNxNDBXeSRtXioDgO1zU8ataeZ2RE4Utao924RFXQ9iHXwvoPHKpW1xY4g_Bg0cSVhKS0p560Za95612ZC02ONrD8ZJYdZp_rGQ37ff_mSP86Np2TWZaNNmdcH56P4P67K66_SXoK9pG-5dF5Z9QEAAA==)): ```svelte ``` ```svelte ``` props は一時的に再代入(reassign)することができます。一方で、[bindable]($bindable) でない限り変異(mutate)すべきではありません。 prop が通常のオブジェクトの場合、変異させても何の効果もありません ([デモ](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2W1QmorQgJXk0RC3PkBwiExG9WQrC17U4Es_ztKUkQp9OjxzM7bjcjtSKjwyfKNp1aLORA4b13ADHszUED1HFE-3eyaBcy-Mw_O5eFAg8xa1wb6T9eWhVgCKiyD9sZJ3XAjZnTWCzzuzfAKvbcjbPJieR2jm_uGy-InweXqtd0baaliBG0nFgW3kBIUNWYo9CGoxE-UsgvIpw2_oc9-LmAPJBCPDJCggqvlVtvdH9puErEMlvVg9HsVtzuoaojzkKKAfRuALVDfk5ZZW0fmy05wXcFdwyktlUs-KIinljTXrRVnm7-kL9dYLVbUAQAA)): ```svelte ``` ```svelte ``` props がリアクティブな state proxy の場合、変異(mutation)は反映されますが、[`ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation) 警告が表示されます。これは、そのコンポーネントが「所有していない」state を変異(mutate)しているためです ([デモ](/playground/untitled#H4sIAAAAAAAAE3WR0U7DMAxFf8VESBuiauG1WycheOEbKA9p67FA6kSNszJV-XeUZhMw2GN8r-1znUmQ7FGU4pn2UqsOes-SlSGRia3S6ET5Mgk-2OiJBZGdOh6szd0eNcdaIx3-V28NMRI7UYq1awdleVNTzaq3ZmB43CndwXYwPSzyYn4dWxermqJRI4Np3rFlqODasWRcTtAaT1zCHYSbVU3r4nsyrdPMKTUFKDYiE4yfLEoePIbsQpqfy3_nOVMuJIqg0wk1RFg7GOuWfwEbz2wIDLVatR_VtLyBagNTHFIUMCqtoZXeIfAOU1JoUJsR2IC3nWTMjt7GM4yKdyBhlAMpesvhydCC0y_i0ZagHByMh26WzUhXUUxKnpbcVnBfUwhznJnNlac7JkuIURL-2VVfwxflyrWcSQIAAA==)): ```svelte ``` ```svelte ``` `$bindable` として宣言されていない props のフォールバック値はそのままです — リアクティブな state proxy には変換されません — つまり変異(mutation)しても更新は発生しません ([デモ](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2VkIbUVoYFraCIh7vwA4eC4G9Wta1vxpgJZ_nfkBEQp9OjxzOzTRGHlkUQlXpy9G0gq1idCL43ppDrAD84HUYheGwqieo2CP3y2Z0EU3-En79fhRIaz1slA_-nKWSbLQVRiE9SgPTetbVkfvRsYzztttugHd8RiXU6vr-jisbWb8idhN7O3bEQhmN5ZVDyMlIorcOddv_Eufq4AGmJEuG5PilEjQrnRcoV7JCTUuJlGWq7-YHYjs7NwVhmtDnVcrlA3iLmzLLGTAdaB-j736h68Oxv-JM1I0AFjoG1OzPfX023c1nhobUoT39QeKsRzS8owM8DFTG_pE6dcVl70AQAA)) ```svelte ``` 要約: props を変異(mutate)しないでください。変更を伝えるためにコールバック props を使用するか、親と子が同じオブジェクトを共有する必要がある場合は [`$bindable`]($bindable) rune を使用してください。 ## Type safety 他の変数宣言と同様に、props にアノテーションを付けることでコンポーネントに型安全性を追加できます。TypeScript では次のようになります... ```svelte ``` ...一方、JSDoc では次のようにできます: ```svelte ``` もちろん、型宣言をアノテーションから分離することもできます: ```svelte ``` > [!NOTE] ネイティブ DOM 要素用のインターフェースは `svelte/elements` モジュールで提供されています ([Typing wrapper components](typescript#Typing-wrapper-components) を参照してください) 型を追加することをお勧めします。これにより、コンポーネントを使用する人々が、渡すべき props を簡単に発見できるようになります。 ## `$props.id()` This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered component, the value will be consistent between server and client. This is useful for linking elements via attributes like `for` and `aria-labelledby`. ```svelte
``` # $bindable 通常、props は親から子へ一方向に流れます。これにより、アプリ内のデータの流れを簡単に理解することができます。 Svelte では、コンポーネントの props を _バインド_ することができ、データを子から親へと _逆方向_ に流すこともできます。これは頻繁に行うべきことではありませんが、慎重かつ控えめに使用すればコードを簡素化できます。 また、子コンポーネント内で state proxy を _変異_ (mutate) できることを意味します。 > [!NOTE] 通常の props でも変異(Mutation)は可能ですが、これは強く非推奨です — Svelte は、コンポーネントが「所有していない」state を変更していることを検出すると警告を表示します。 props をバインド可能 (bindable) としてマークするには、`$bindable` rune を使用します: ```svelte /// file: FancyInput.svelte ``` これで、`` を使用するコンポーネントに [`bind:`](bind) ディレクティブを追加することができます ([デモ](/playground/untitled#H4sIAAAAAAAAE3WQwWrDMBBEf2URBSfg2nfFMZRCoYeecqx6UJx1IyqvhLUONcb_XqSkTUOSk1az7DBvJtEai0HI90nw6FHIJIhckO7i78n7IhzQctS2OuAtvXHESByEFFVoeuO5VqTYdN71DC-amvGV_MDQ9q6DrCjP0skkWymKJxYZOgxBfyKs4SGwZlxke7TWZcuVoqo8-1P1z3lraCcP2g64nk4GM5S1osrXf0JV-lrkgvGbheR-wDm_g30V8JL-1vpOCZFogpQsEsWcemtxscyhKArfOx9gjps0Lq4hzRVfemaYfu-PoIqqwKPFY_XpaIqj4tYRP7a6M3aUkD27zjSw0RTgbZN6Z8WNs66XsEP03tBXUueUJFlelvYx_wCuI3leNwIAAA==)): ```svelte /// file: App.svelte

{message}

``` 親コンポーネントは必ずしも `bind:` を使用する必要はありません — その場合、通常の props を渡すだけで構いません。子の発言を聞きたくない親もいるかもしれません。 この場合、何も props が渡されないときのフォールバック値を指定することができます: ```js /// file: FancyInput.svelte let { value = $bindable('fallback'), ...props } = $props(); ``` # $inspect > [!NOTE] `$inspect` は開発中のみ動作します。本番ビルドでは何もしない (noop) ものになります。 `$inspect` rune はおおむね `console.log` と同等ですが、引数が変更されるたびに再実行される点が異なります。`$inspect` はリアクティブな state を深く追跡し、オブジェクトや配列内のプロパティやアイテムなどをきめ細やかなリアクティビティで更新すると、再度発火します ([デモ](/playground/untitled#H4sIAAAAAAAACkWQ0YqDQAxFfyUMhSotdZ-tCvu431AXtGOqQ2NmmMm0LOK_r7Utfby5JzeXTOpiCIPKT5PidkSVq2_n1F7Jn3uIcEMSXHSw0evHpAjaGydVzbUQCmgbWaCETZBWMPlKj29nxBDaHj_edkAiu12JhdkYDg61JGvE_s2nR8gyuBuiJZuDJTyQ7eE-IEOzog1YD80Lb0APLfdYc5F9qnFxjiKWwbImo6_llKRQVs-2u91c_bD2OCJLkT3JZasw7KLA2XCX31qKWE6vIzNk1fKE0XbmYrBTufiI8-_8D2cUWBA_AQAA)): ```svelte ``` ## $inspect(...).with `$inspect` は `with` プロパティを返します。このプロパティにはコールバックを渡すことができ、`console.log` の代わりにそのコールバックが呼び出されます。コールバックの最初の引数は `"init"` または `"update"` で、以降の引数には `$inspect` に渡された値が含まれます ([デモ](/playground/untitled#H4sIAAAAAAAACkVQ24qDMBD9lSEUqlTqPlsj7ON-w7pQG8c2VCchmVSK-O-bKMs-DefKYRYx6BG9qL4XQd2EohKf1opC8Nsm4F84MkbsTXAqMbVXTltuWmp5RAZlAjFIOHjuGLOP_BKVqB00eYuKs82Qn2fNjyxLtcWeyUE2sCRry3qATQIpJRyD7WPVMf9TW-7xFu53dBcoSzAOrsqQNyOe2XUKr0Xi5kcMvdDB2wSYO-I9vKazplV1-T-d6ltgNgSG1KjVUy7ZtmdbdjqtzRcphxMS1-XubOITJtPrQWMvKnYB15_1F7KKadA_AQAA)): ```svelte ``` 変更の起点を見つける便利な方法は、`with` に `console.trace` を渡すことです: ```js // @errors: 2304 $inspect(stuff).with(console.trace); ``` ## $inspect.trace(...) この rune は 5.14 で追加され、開発中に周囲の関数を _トレース_ することを可能にします。関数が [effect]($effect) または [derived]($derived) の一部として再実行されるたびに、どのリアクティブ state がその effect を引き起こしたかについての情報がコンソールに出力されます。 ```svelte ``` `$inspect.trace` はオプションで第1引数を受け取り、これがラベルとして使用されます。 # $host コンポーネントを[カスタム要素 (custom element)](custom-elements) としてコンパイルする際、`$host` rune を使用するとホスト要素 (host element) にアクセスでき、(例えば)custom event をディスパッチすることができます ([デモ](/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} >

count: {count}

``` # Basic markup Svelte コンポーネント内のマークアップは、HTML++ と考えることができます。 ## Tags 小文字のタグ (`
` のようなもの) は通常の HTML 要素を表します。一方、大文字で始まるタグやドット表記を使用したタグ (`` や `` など) は _コンポーネント_ を表します。 ```svelte
``` ## Element attributes デフォルトでは、属性は HTML のそれと同じように動作します。 ```svelte
``` HTML と同様に、値は引用符なしでも指定することができます。 ```svelte ``` 属性値には JavaScript の式を含めることができます。 ```svelte page {p} ``` または、それ自体を JavaScript の式にすることも可能です。 ```svelte ``` Boolean の属性は、その値が [truthy](https://developer.mozilla.org/ja/docs/Glossary/Truthy) であれば要素に含まれ、[falsy](https://developer.mozilla.org/ja/docs/Glossary/Falsy) であれば除外されます。 その他の属性は、値が [nullish](https://developer.mozilla.org/ja/docs/Glossary/Nullish) (`null` または `undefined`) でない限り含まれます。 ```svelte
This div has no title attribute
``` > [!NOTE] 単一の式を引用符で囲むことは値のパース方法に影響しませんが、Svelte 6 では値が文字列に変換されるようになります: > > > ```svelte > > ``` 属性名と値が一致する場合 (`name={name}`)、`{name}` という形で簡略化できます。 ```svelte ``` ## Component props 慣習として、コンポーネントに渡される値は、DOM の機能である _属性_ ではなく、_プロパティ_ または _props_ と呼ばれます。 要素の場合と同様に、`name={name}` は `{name}` の短縮形に置き換えることができます。 ```svelte ``` ## Spread attributes _スプレッド属性(Spread attributes)_ を使用すると、複数の属性やプロパティを一度に要素やコンポーネントに渡すことができます。 要素やコンポーネントは複数のスプレッド属性を置くことができますし、通常の属性と一緒に使用することもできます。順序が重要です。`things.a` が存在する場合、`a="b"` より優先されますが、`c="d"` は `things.c` より優先されます。 ```svelte ``` ## Events DOM イベントを監視するには、要素に `on` で始まる属性を追加します。例えば、`click` イベントを監視するには、ボタンに `onclick` 属性を追加します: ```svelte ``` イベント属性は大文字小文字を区別します。`onclick` は `click` イベントを監視し、`onClick` は異なる `Click` イベントを監視します。これにより、大文字を含むカスタムイベントを監視することが可能になります。 イベントは単なる属性であるため、属性と同じルールが適用されます: - 短縮形を使用できます: `` - スプレッドも使用できます: `` タイミング的に、イベント属性は常にバインディングのイベントの後に発火します (例えば、`oninput` は `bind:value` の更新後に発火します)。内部では、一部のイベントハンドラーは `addEventListener` を使用して直接アタッチされ、その他は _委任(delegate)_ されます。 `ontouchstart` や `ontouchmove` イベント属性を使用する場合、ハンドラーは [passive](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener#パッシブリスナーの使用) として動作し、パフォーマンスが向上します。これにより、イベントハンドラーが `event.preventDefault()` を呼び出すかどうかを待つのではなく、ブラウザが即座にドキュメントをスクロールできるようになり、レスポンシブ性が大幅に改善されます。 これらのイベントのデフォルト動作を防ぐ必要がある非常に稀な場合には、代わりに [`on`](svelte-events#on) を使用するべきです (例えば action 内で)。 ### Event delegation メモリ消費を減らし、パフォーマンスを向上させるため、Svelte はイベントデリゲーション (event delegation) というテクニックを使用しています。これは、以下のリストにある特定のイベントについては、アプリケーションルートの単一のイベントリスナーがイベントのパス上のハンドラーを実行する役割を担うことを意味します。 注意すべきポイントがいくつかあります: - 委任されたリスナー(delegated listener)でイベントを手動でディスパッチする場合、`{ bubbles: true }` オプションを設定してください。さもないとアプリケーションルートに到達しません。 - `addEventListener` を直接使用する場合、`stopPropagation` を呼び出さないようにしてください。そうしないと、イベントがアプリケーションルートに到達せず、ハンドラーが実行されなくなります。同様に、アプリケーションルート内に手動で追加されたハンドラーは、DOM の深い場所に宣言的に追加されたハンドラー (例えば `onclick={...}` など) よりも _前に_ 実行されます (キャプチャおよびバブリングフェーズの両方で)。これらの理由から、`addEventListener` よりも `svelte/events` からインポートされる `on` 関数を使用する方が、順序が保持され、`stopPropagation` が正しく処理されるため推奨されます。 以下のイベントハンドラーが委任(delegate)されます: - `beforeinput` - `click` - `change` - `dblclick` - `contextmenu` - `focusin` - `focusout` - `input` - `keydown` - `keyup` - `mousedown` - `mousemove` - `mouseout` - `mouseover` - `mouseup` - `pointerdown` - `pointermove` - `pointerout` - `pointerover` - `pointerup` - `touchend` - `touchmove` - `touchstart` ## Text expressions JavaScript 式は中括弧 `{}` で囲むことでテキストとして含めることができます。 ```svelte {expression} ``` `null` や `undefined` となる式は省略されます; それ以外はすべて [String](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion) に変換されます。 中括弧は、その [HTML エンティティ](https://developer.mozilla.org/ja/docs/Glossary/Entity) 文字列を使用することで Svelte テンプレート内に含めることができます。`{` の場合は `{`, `{`, または `{`、`}` の場合は `}`, `}`, または `}` を使用します。 正規表現 (`RegExp`) の [リテラル表記](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp#リテラル記法とコンストラクター) を使用する場合、それを括弧で囲む必要があります。 ```svelte

Hello {name}!

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

{(/^[A-Za-z ]+$/).test(value) ? x : y}
``` 式は文字列化され、コードインジェクションを防ぐためにエスケープされます。HTML をレンダリングしたい場合は、代わりに `{@html}` タグを使用してください。 ```svelte {@html potentiallyUnsafeHtmlString} ``` > [!NOTE] 渡される文字列をエスケープするか、または自分がコントロールできる値でのみ埋めるようにして、[XSS 攻撃](https://owasp.org/www-community/attacks/xss/) を防止してください。 ## Comments コンポーネント内で HTML コメントを使用することができます。 ```svelte

Hello world

``` `svelte-ignore` で始まるコメントは、その次にくるマークアップブロックに対する警告を無効にします。通常、これらはアクセシビリティに関する警告であることが多いですが、適切な理由がある場合にのみ無効化するようにしてください。 ```svelte ``` `@component` で始まる特別なコメントを追加することで、他のファイルでコンポーネント名にカーソルを合わせたときに表示されるコメントを作成できます。 ````svelte

Hello, {name}

```` # {#if ...} ```svelte {#if expression}...{/if} ``` ```svelte {#if expression}...{:else if expression}...{/if} ``` ```svelte {#if expression}...{:else}...{/if} ``` 条件付きでレンダリングされるコンテンツは、if ブロックで囲むことができます。 ```svelte {#if answer === 42}

what was the question?

{/if} ``` `{:else if expression}` を使用して追加の条件を指定することができ、`{:else}` 句で終わらせることもできます。 ```svelte {#if porridge.temperature > 100}

too hot!

{:else if 80 > porridge.temperature}

too cold!

{:else}

just right!

{/if} ``` (ブロックは要素を囲む必要はなく、要素内のテキストを囲むこともできます。) # {#each ...} ```svelte {#each expression as name}...{/each} ``` ```svelte {#each expression as name, index}...{/each} ``` 値を繰り返し処理するには、each ブロックを使用します。対象の値は配列、配列のようなオブジェクト (例えば `length` プロパティを持つような)、または `Map` や `Set` のようなイテラブルである必要があります — つまり、`Array.from` を使用できるものであれば問題ありません。 ```svelte

Shopping list

    {#each items as item}
  • {item.name} x {item.qty}
  • {/each}
``` each ブロックは _インデックス_ も指定可能で、これは `array.map(...)` コールバックの第二引数に相当します: ```svelte {#each items as item, i}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} ``` ## Keyed each blocks ```svelte {#each expression as name (key)}...{/each} ``` ```svelte {#each expression as name, index (key)}...{/each} ``` _key_ の式(各リストアイテムを一意に識別できる必要があります)が与えられた場合、Svelte は、データがアイテムの挿入・移動・削除によって変化したとき、リストの末尾にアイテムを追加・削除して途中のアイテムを更新するのではなく、その key を使用して賢くリストを更新します。 key はどんなオブジェクトでもよいですが、そのオブジェクト自体が変更されたときに同一性を維持できるため、文字列か数値を推奨します。 ```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} ``` 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} ``` ## Each blocks without an item ```svelte {#each expression}...{/each} ``` ```svelte {#each expression, index}...{/each} ``` もし `n` 回レンダリングしたいだけの場合は、`as` 部分を省略することができます ([デモ](/playground/untitled#H4sIAAAAAAAAE3WR0W7CMAxFf8XKNAk0WsSeUEaRpn3Guoc0MbQiJFHiMlDVf18SOrZJ48259_jaVgZmxBEZZ28thgCNFV6xBdt1GgPj7wOji0t2EqI-wa_OleGEmpLWiID_6dIaQkMxhm1UdwKpRQhVzWSaVORJNdvWpqbhAYVsYQCNZk8thzWMC_DCHMZk3wPSThNQ088I3mghD9UwSwHwlLE5PMIzVFUFq3G7WUZ2OyUvU3JOuZU332wCXTRmtPy1NgzXZtUFp8WFw9536uWqpbIgPEaDsJBW90cTOHh0KGi2XsBq5-cT6-3nPauxXqHnsHJnCFZ3CvJVkyuCQ0mFF9TZyCQ162WGvteLKfG197Y3iv_pz_fmS68Hxt8iPBPj5HscP8YvCNX7uhYCAAA=)): ```svelte
    {#each { length: 8 }, rank} {#each { length: 8 }, file}
    {/each} {/each}
    ``` ## Else blocks ```svelte {#each expression as name}...{:else}...{/each} ``` each ブロックは `{:else}` 節を持つことができ、リストが空の場合にそれがレンダリングされます。 ```svelte {#each todos as todo}

    {todo.text}

    {:else}

    No tasks today!

    {/each} ``` # {#key ...} ```svelte {#key expression}...{/key} ``` key ブロックは、式の値が変化したときにその内容を破棄して再生成します。コンポーネントを囲んで使用した場合、コンポーネントの再インスタンス化され、再初期化されます: ```svelte {#key value} {/key} ``` 値が変更されるたびにトランジションを再生したい場合にも便利です: ```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} ``` await ブロックを使用すると、[`Promise`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise) の 3 つの可能な状態 — 待機 (pending)、成功 (fulfilled)、または失敗 (rejected) — に応じて処理を分岐させることができます。 ```svelte {#await promise}

    waiting for the promise to resolve...

    {:then value}

    The value is {value}

    {:catch error}

    Something went wrong: {error.message}

    {/await} ``` > [!NOTE] サーバーサイドレンダリング中は、待機中の分岐のみがレンダリングされます。 > > 提供された式が `Promise` でない場合は、サーバーサイドレンダリング中も含め、`:then` の分岐のみがレンダリングされます。 promise が失敗した場合に何もレンダリングする必要がない場合 (またはエラーが発生しない場合)、`catch` ブロックを省略できます。 ```svelte {#await promise}

    waiting for the promise to resolve...

    {:then value}

    The value is {value}

    {/await} ``` 待機中の状態を気にしない場合、最初のブロックを省略することもできます。 ```svelte {#await promise then value}

    The value is {value}

    {/await} ``` 同様に、エラー状態のみを表示したい場合は、`then` ブロックを省略できます。 ```svelte {#await promise catch error}

    The error is {error}

    {/await} ``` > [!NOTE] `#await` を [`import(...)`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/import) と組み合わせることで、コンポーネントを遅延的 (lazily) にレンダリングすることができます: > > ```svelte > {#await import('./Component.svelte') then { default: Component }} > > {/await} > ``` # {#snippet ...} ```svelte {#snippet name()}...{/snippet} ``` ```svelte {#snippet name(param1, param2, paramN)}...{/snippet} ``` Snippet と [render タグ](@render) を使用すると、コンポーネント内で再利用可能なマークアップのチャンクを作成することができます。このような重複が多い[コード](/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} ``` ...[このように](/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} ``` 関数宣言と同様に、snippet は任意の数のパラメーターを持つことができ、それぞれにデフォルト値を設定したり、分割代入を使用することができます。ただし、残余引数 (rest parameters) は使用できません。 ## Snippet scope snippet はコンポーネント内の任意の場所で宣言できます。その snippet の外側、例えば ` {#snippet hello(name)}

    hello {name}! {message}!

    {/snippet} {@render hello('alice')} {@render hello('bob')} ``` ...また、同じレキシカルスコープ内のすべての要素 (つまり兄弟要素やその子要素) から '見える (visible)' 状態になります: ```svelte
    {#snippet x()} {#snippet y()}...{/snippet} {@render y()} {/snippet} {@render y()}
    {@render x()} ``` snippet は、自身や他の snippet を参照することができます ([デモ](/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)} ``` ## snippet をコンポーネントに渡す ### Explicit props テンプレート内では、snippet は他の値と同じように扱われます。そのため、snippet は props としてコンポーネントに渡すことができます ([デモ](/playground/untitled#H4sIAAAAAAAAE3VS247aMBD9lZGpBGwDASRegonaPvQL2qdlH5zYEKvBNvbQLbL875VzAcKyj3PmzJnLGU8UOwqSkd8KJdaCk4TsZS0cyV49wYuJuQiQpGd-N2bu_ooaI1YwJ57hpVYoFDqSEepKKw3mO7VDeTTaIvxiRS1gb_URxvO0ibrS8WanIrHUyiHs7Vmigy28RmyHHmKvDMbMmFq4cQInvGSwTsBYWYoMVhCSB2rBFFPsyl0uruTlR3JZCWvlTXl1Yy_mawiR_rbZKZrellJ-5JQ0RiBUgnFhJ9OGR7HKmwVoilXeIye8DOJGfYCgRlZ3iE876TBsZPX7hPdteO75PC4QaIo8vwNPePmANQ2fMeEFHrLD7rR1jTNkW986E8C3KwfwVr8HSHOSEBT_kGRozyIkn_zQveXDL3rIfPJHtUDwzShJd_Qk3gQCbOGLsdq4yfTRJopRuin3I7nv6kL7ARRjmLdBDG3uv1mhuLA3V2mKtqNEf_oCn8p9aN-WYqH5peP4kWBl1UwJzAEPT9U7K--0fRrrWnPTXpCm1_EVdXjpNmlA8G1hPPyM1fKgMqjFHjctXGjLhZ05w0qpDhksGrybuNEHtJnCalZWsuaTlfq6nPaaBSv_HKw-K57BjzOiVj9ZKQYKzQjZodYFqydYTRN4gPhVzTDO2xnma3HsVWjaLjT8nbfwHy7Q5f2dBAAA)): ```svelte {#snippet header()} fruit qty price total {/snippet} {#snippet row(d)} {d.name} {d.qty} {d.price} {d.qty * d.price} {/snippet} ``` データの代わりにコンテンツをコンポーネントに渡すようなものと考えてください。このコンセプトは web component の slot に似ています。 ### Implicit props 作成を簡単にするため、コンポーネント内に直接宣言された snippet は、自動的にそのコンポーネントの props になります ([デモ](/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 qty price total{d.name} {d.qty} {d.price} {d.qty * d.price}
    ``` ### Implicit `children` snippet コンポーネントタグ内で、snippet 宣言でないすべてのコンテンツは、自動的に `children` snippet の一部になります ([デモ](/playground/untitled#H4sIAAAAAAAAE3WOQQrCMBBFrzIMggql3ddY1Du4si5sOmIwnYRkFKX07lKqglqX8_7_w2uRDw1hjlsWI5ZqTPBoLEXMdy3K3fdZDzB5Ndfep_FKVnpWHSKNce1YiCVijirqYLwUJQOYxrsgsLmIOIZjcA1M02w4n-PpomSVvTclqyEutDX6DA2pZ7_ABIVugrmEC3XJH92P55_G39GodCmWBFrQJ2PrQAwdLGHig_NxNv9xrQa1dhWIawrv1Wzeqawa8953D-8QOmaEAQAA)): ```svelte ``` ```svelte ``` > [!NOTE] コンポーネント内にコンテンツがある場合、`children` という名前の props を持つことはできません — このため、その名前の props を避けるべきです。 ### Optional snippet props snippet の props をオプションとして宣言することができます。snippet が設定されていない場合は、オプショナルチェーン (optional chaining) を使用して何もレンダリングしないようにするか... ```svelte {@render children?.()} ``` ...または、`#if` ブロックを使用してフォールバックコンテンツをレンダリングすることができます: ```svelte {#if children} {@render children()} {:else} fallback content {/if} ``` ## snippet に型を付ける snippet は、`'svelte'` からインポートされる `Snippet` インターフェースを実装します: ```svelte ``` この変更により、`data` プロパティと `row` snippet を提供せずにコンポーネントを使用しようとすると、赤い波線が表示されるようになります。snippet には複数のパラメーターを持たせることができるため、`Snippet` に提供される型引数がタプルになっていることに注意してください。 generic を宣言することで、`data` と `row` が同じ型を参照するように、さらに厳密にすることができます: ```svelte ``` ## snippet をエクスポートする `.svelte` ファイルのトップレベルで宣言された snippet は、non-module な ` {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` > [!NOTE] > これには Svelte 5.5.0 以上が必要です ## プログラマティックな snippet snippet は、[`createRawSnippet`](svelte#createRawSnippet) API を使用してプログラムで作成することができます。これは高度なユースケースを意図しています。 ## Snippet と slot Svelte 4 では、[slot](legacy-slots) を使用してコンテンツをコンポーネントに渡すことができます。snippet はより強力で柔軟性があるため、Svelte 5 では slot は非推奨となりました。 # {@render ...} [snippet](snippet) をレンダリングするには、`{@render ...}` タグを使用します。 ```svelte {#snippet sum(a, b)}

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

    {/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)} ``` 式は `sum` のような識別子、または任意の JavaScript 式にすることができます: ```svelte {@render (cool ? coolSnippet : lameSnippet)()} ``` ## Optional snippets snippet が undefined である可能性がある場合 — 例えば、それが外部から渡されたプロパティである場合、オプショナルチェーン(optional chaining)を使用して、それが定義されている場合のみレンダリングすることができます: ```svelte {@render children?.()} ``` または、[`{#if ...}`](if) ブロックを `:else` 句と組み合わせて使用し、フォールバックコンテンツをレンダリングします: ```svelte {#if children} {@render children()} {:else}

    fallback content

    {/if} ``` # {@html ...} 生の HTML をコンポーネントに挿入するには、`{@html ...}` タグを使用します: ```svelte
    {@html content}
    ``` > [!NOTE] 渡された文字列をエスケープするか、または自分がコントロールできる値でのみ埋めるようにして、[XSS 攻撃](https://owasp.org/www-community/attacks/xss/) を防止してください。サニタイズされていないコンテンツをレンダリングしてはいけません。 式は単体で有効な HTML である必要があります — 例えば、`
    ` は有効な HTML ではないため機能しません: ```svelte {@html '
    '}content{@html '
    '} ``` また、Svelte のコードをコンパイルすることもできません。 ## Styling この方法でレンダリングされたコンテンツは Svelte からは '見えない(invisible)' ため、[スコープ付きスタイル](scoped-styles) を適用することはできません — 言い換えると、次の例は機能せず、`a` と `img` のスタイルは未使用と見なされます: ```svelte
    {@html content}
    ``` 代わりに、`:global` 修飾子を使用して `
    ` 内のすべてをターゲットにします: ```svelte ``` # {@attach ...} Attachments are functions that run in an [effect]($effect) when an element is mounted to the DOM or when [state]($state) read inside the function updates. Optionally, they can return a function that is called before the attachment re-runs, or after the element is later removed from the DOM. > [!NOTE] > Attachments are available in Svelte 5.29 and newer. ```svelte
    ...
    ``` An element can have any number of attachments. ## Attachment factories A useful pattern is for a function, such as `tooltip` in this example, to _return_ an attachment ([demo](/playground/untitled#H4sIAAAAAAAAE3VT0XLaMBD8lavbDiaNCUlbHhTItG_5h5AH2T5ArdBppDOEMv73SkbGJGnH47F9t3un3TsfMyO3mInsh2SW1Sa7zlZKo8_E0zHjg42pGAjxBPxp7cTvUHOMldLjv-IVGUbDoUw295VTlh-WZslqa8kxsLL2ACtHWxh175NffnQfAAGikSGxYQGfPEvGfPSIWtOH0TiBVo2pWJEBJtKhQp4YYzjG9JIdcuMM5IZqHMPioY8vOSA997zQoevf4a7heO7cdp34olRiTGr07OhwH1IdoO2A7dLMbwahZq6MbRhKZWqxk7rBxTGVbuHmhCgb5qDgmIx_J6XtHHukHTrYYqx_YpzYng8aO4RYayql7hU-1ZJl0akqHBE_D9KLolwL-Dibzc7iSln9XjtqTF1UpMkJ2EmXR-BgQErsN4pxIJKr0RVO1qrxAqaTO4fbc9bKulZm3cfDY3aZDgvFGErWjmzhN7KmfX5rXyDeX8Pt1mU-hXjdBOrtuB97vK4GPUtmJ41XcRMEGDLD8do0nJ73zhUhSlyRw0t3vPqD8cjfLs-axiFgNBrkUd9Ulp50c-GLxlXAVlJX-ffpZyiSn7H0eLCUySZQcQdXlxj4El0Yv_FZvIKElqqGTruVLhzu7VRKCh22_5toOyxsWqLwwzK-cCbYNdg-hy-p9D7sbiZWUnts_wLUOF3CJgQAAA==)): ```svelte ``` Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs. (If this isn't what you want, see [Controlling when attachments re-run](#Controlling-when-attachments-re-run).) ## Inline attachments Attachments can also be created inline ([demo](/playground/untitled#H4sIAAAAAAAAE71Wf3OaWBT9KoyTTnW3MS-I3dYmnWXVtnRAazRJzbozRSQEApiRhwKO333vuY8m225m_9yZGOT9OPfcc84D943UTfxGr_G7K6Xr3TVeNW7D2M8avT_3DVk-YAoDNF4vNB8e2tnWjyXGlm7mPzfurVPpp5JgGmeZtwkf5PtFupCxLzVvHa832rl2lElX-s2Xm2DZFNqp_hs-rZetd4v07ORpT3qmQHu7MF2td0BZp8k6z_xkvfXP902_pZ2_1_aYWEiqm0kN8I4r79qbdZ6umnq3q_2iNf22F4dE6qt2oimwdpim_uY6XMm7Fuo-IQT_iTD_CeGTHwZ38ieIJUFQRxirR1Xf39Dw0X5z0I72Af4tD61vvPNwWKQnqmfPTbduhsEd2J3vO_oBd3dc6fF2X7umNdWGf0vBRhSS6qoV7cCXfTXWfKmvWG61_si_vfU92Wz-E4RhsLhNIYinsox9QKGVd8-tuACCeKXRX12P-T_eKf7fhTq0Hvt-f3ailtSeoxJHRo1-58NoPe1UiBc1hkL8Yeh45y_vQ3mcuNl9T8s3cXPRWLnS7YWJG_gn2Tb4tUjid8jua-PVl08j_ab8I14mH8Llx0s5Tz5Err4ql52r_GYg0mVy1bEGZuD0ze64b5TWYFiM-16wSuJ4JT5vfVpDcztrcG_YkRU4s6HxufzDWF4XuVeJ1P10IbzBemt3Vp1V2e04ZXfrJd7Wicyd039brRIv_RIVu_nXi7X1cfL2sy66ztToUp1TO7qJ7NlwZ0f30pld5qNSVE5o6PbMojFHjgZB7oSicPpGteyLclQap7SvY0dXtM_LR1NT2JFHey3aaxa0VxCeYJ7RMHemoiCcgPZV9pR7o7kgcOjeGliYk9hjDZx8FAq6enwlTPSZj_vYPw9Il64dXdIY8ZmapzwfEd8-1ZyaxWhqkIZOibXUd-6Upqi1pD4uMicCV1GA_7zi73UN8BaF4sC8peJtMjfmjbHZBFwq5ov50qRaE0l96NZggnW4KqypYRAW-uhSz9ADvklwJF2J-5W0Z5fQPBhDX92R6I_0IFxRgDftge4l4dP-gH1hjD7uqU6fsOEZ9UNrCdPB-nys6uXgY6O3ZMd9sy5T9PghqrWHdjo4jB51CgLiKJaDYYA-7WgYONf1FbjkI-mE3EAfUY_rijfuJ_CVPaR50oe9JF7Q0pI8Dw3osxxYHdYPGbp2CnwHF8KvwJv2wEv0Z3ilQI6U9uwbZxbYJXvEmjjQjjCHkvNLvNg3yhzXQd1olamsT4IRrZmX0MUDpwL7R8zzHj7pSh9hPHFSHjLezKqAST51uC5zmtQ87skDUaneLokT5RbXkPWSYz53Abgjc8_o4KFGUZ-Hgv2Z1l5OTYM9D-HfUD0L-EwxH5wRnIG61gS-khfgY1bq7IAP_DA4l5xRuh9xlm8yGjutc8t-wHtkhWv3hc7aqGwiK5KzgvM5xRkZYn193uEln-su55j1GaIv7oM4iPrsVHiG0Dx7TR9-1lBfqFdwfvSd5LNL5xyZVp5NoHFZ57FkfiF6vKs4k5zvIfrX5xX6MXmt0gM5MTu8DjnhukrHHzTRd3jm0dma0_f_x5cxP9f4jBdqHvmbq2fUjzqcKh2Cp-yWj9ntcHanXmBXxhu7Q--eyjhfNFpaV7zgz4nWEUb7zUOhpevjjf_gu_KZ99pxFlZ-T3sttkmYqrco_26q35v0Ewzv5EZPbnL_8BfduWGMnyyN3q0bZ_7hb_7KG_L4CQAA)): ```svelte { const context = canvas.getContext('2d'); $effect(() => { context.fillStyle = color; context.fillRect(0, 0, canvas.width, canvas.height); }); }} > ``` > [!NOTE] > The nested effect runs whenever `color` changes, while the outer effect (where `canvas.getContext(...)` is called) only runs once, since it doesn't read any reactive state. ## Passing attachments to components When used on a component, `{@attach ...}` will create a prop whose key is a [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol). If the component then [spreads](/tutorial/svelte/spread-props) props onto an element, the element will receive those attachments. This allows you to create _wrapper components_ that augment elements ([demo](/playground/untitled#H4sIAAAAAAAAE3VUS3ObMBD-KxvajnFqsJM2PhA7TXrKob31FjITAbKtRkiMtDhJPfz3LiAMdpxhGJvdb1_fPnaeYjn3Iu-WIbJ04028lZDcetHDzsO3olbVApI74F1RhHbLJdayhFl-Sp5qhVwhufEWNjWiwJtYxSjyQhsEFEXxBiujcxg1_8O_dnQ9APwsEbVyiHDafjrvDZCgkiO4MLCEzxYZcn90z6XUZ6OxA61KlaIgV6i1pFC-sxjDrlbHaDiWRoGvdMbHsLzp5DES0mJnRxGaRBvcBHb7yFUTCQeunEWYcYtGv12TqgFUDbCK1WLaM6IWQhUlQiJUFm2ZLPly51xXMG0Rjoyd69C7UqqG2nu95QZyXvtvLVpri2-SN4hoLXXCZFfhQ8aQBU1VgdEaH_vSgyBZR_BpPp_vi0tY-rw2ulRZkGqpTQRbZvwa2BPgFC8bgbw31CbjJjAsE6WNYBZeGp7vtQXLMqHWnZx-5kM1TR5ycpkZXQR2wzL94l8Ur1C_3-g168SfQf1MyfRi3LW9fs77emJEw5QV9SREoLTq06tcczq7d6xEUcJX2vAhO1b843XK34e5unZEMBr15ekuKEusluWAF8lXhE2ZTP2r2RcIHJ-163FPKerCgYJLOB9i4GvNwviI5-gAQiFFBk3tBTOU3HFXEk0R8o86WvUD64aINhv5K3oRmpJXkw8uxMG6Hh6JY9X7OwGSqfUy9tDG3sHNoEi0d_d_fv9qndxRU0VClFqo3KVo3U655Hnt1PXB3Qra2Y2QGdEwgTAMCxopsoxOe6SD0gD8movDhT0LAnhqlE8gVCpLWnRoV7OJCkFAwEXitrYL1W7p7pbiE_P7XH6E_rihODm5s52XtiH9Ekaw0VgI9exadWL1uoEYjPtg2672k5szsxbKyWB2fdT0w5Y_0hcT8oXOlRetmLS8-g-6TLXXQgYAAA==)): ```svelte ``` ```svelte ``` ## Controlling when attachments re-run Attachments, unlike [actions](use), are fully reactive: `{@attach foo(bar)}` will re-run on changes to `foo` _or_ `bar` (or any state read inside `foo`): ```js // @errors: 7006 2304 2552 function foo(bar) { return (node) => { veryExpensiveSetupWork(node); update(node, bar); }; } ``` In the rare case that this is a problem (for example, if `foo` does expensive and unavoidable setup work) consider passing the data inside a function and reading it in a child effect: ```js // @errors: 7006 2304 2552 function foo(+++getBar+++) { return (node) => { veryExpensiveSetupWork(node); +++ $effect(() => { update(node, getBar()); });+++ } } ``` ## Creating attachments programmatically To add attachments to an object that will be spread onto a component or element, use [`createAttachmentKey`](svelte-attachments#createAttachmentKey). ## Converting actions to attachments If you're using a library that only provides actions, you can convert them to attachments with [`fromAction`](svelte-attachments#fromAction), allowing you to (for example) use them with components. # {@const ...} `{@const ...}` タグはローカル定数を定義します。 ```svelte {#each boxes as box} {@const area = box.width * box.height} {box.width} * {box.height} = {area} {/each} ``` `{@const}` は、`{#if ...}`、`{#each ...}`、`{#snippet ...}` などのブロックや、``、または `` の直下の子としてのみ使用可能です。 # {@debug ...} `{@debug ...}` タグは、`console.log(...)` の代替手段を提供します。このタグは、特定の変数の値が変更されるたびにその値をログ出力し、開発者ツールが開いている場合はコードの実行を一時停止します。 ```svelte {@debug user}

    Hello {user.firstname}!

    ``` `{@debug ...}` は、変数名をカンマ区切りで指定することができます (任意の式は指定できません)。 ```svelte {@debug user} {@debug user1, user2, user3} {@debug user.firstname} {@debug myArray[0]} {@debug !isReady} {@debug typeof user === 'object'} ``` 引数なしの `{@debug}` タグは、特定の変数ではなく、_何らかの_ state が変化した際にトリガーされる `debugger` ステートメントを挿入します。 # bind: データは通常、親から子へと流れますが、`bind:` ディレクティブを使用すると、データを子から親へ流すことができます。 一般的な構文は `bind:property={expression}` であり、`expression` は [_lvalue_](https://press.rebus.community/programmingfundamentals/chapter/lvalue-and-rvalue/) (つまり、変数やオブジェクトのプロパティ) です。式がプロパティと同じ名前の識別子である場合、式を省略することができます — 言い換えると、以下は等価です: ```svelte ``` Svelte は、バインドされた値を更新するイベントリスナーを作成します。要素が既に同じイベントのリスナーを持っている場合、そのリスナーはバインドされた値が更新される前に実行されます。 ほとんどのバインディングは _双方向_ であり、値の変更が要素に影響し、その逆も同様です。一部のバインディングは _読み取り専用_ であり、値を変更しても要素に影響を与えません。 ## Function bindings `bind:property={get, set}` を使用して、`get` と `set` を関数として指定し、バリデーションや変換を行うことができます: ```svelte value, (v) => value = v.toLowerCase()} /> ``` [dimension bindings](#Dimensions) のような読み取り専用バインディングの場合、`get` の値は `null` にする必要があります: ```svelte
    ...
    ``` > [!NOTE] > Function bindings は Svelte 5.9.0 以降で使用可能です。 ## `` `` 要素に対する `bind:value` ディレクティブは、input の `value` プロパティをバインドします: ```svelte

    {message}

    ``` 数値を扱う input (`type="number"` または `type="range"`) の場合、値は数値に変換されます ([デモ](/playground/untitled#H4sIAAAAAAAAE6WPwYoCMQxAfyWEPeyiOOqx2w74Hds9pBql0IllmhGXYf5dKqwiyILsLXnwwsuI-5i4oPkaUX8yo7kCnKNQV7dNzoty4qSVBSr8jG-Poixa0KAt2z5mbb14TaxA4OCtKCm_rz4-f2m403WltrlrYhMFTtcLNkoeFGqZ8yhDF7j3CCHKzpwoDexGmqCL4jwuPUJHZ-dxVcfmyYGe5MAv-La5pbxYFf5Z9Zf_UJXb-sEMquFgJJhBmGyTW5yj8lnRaD_w9D1dAKSSj7zqAQAA)): ```svelte

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

    ``` 入力が空または無効 (`type="number"` の場合) の場合、値は `undefined` になります。 バージョン 5.6.0 以降、`` に `defaultValue` が設定されていてフォームの一部である場合、フォームがリセットされると空文字列ではなくその値に戻ります。初回のレンダリングでは、バインディングの値が `null` または `undefined` でない限り優先されることに注意してください。 ```svelte
    ``` > [!NOTE] > リセットボタンは慎重に使用し、ユーザーがフォームを送信しようとしているときに誤ってクリックしないようにしてください。 ## `` checkbox および radio の input には、`bind:checked` を使用してバインドできます: ```svelte ``` バージョン 5.6.0 以降、`` に `defaultChecked` 属性が設定されておりフォームの一部である場合、フォームがリセットされると `false` ではなくその値に戻ります。初回のレンダリングでは、バインディングの値が `null` または `undefined` でない限り優先されます。 ```svelte
    ``` ## `` チェックボックスは、それがチェックされているかされていないかに関係なく、[indeterminate](https://developer.mozilla.org/ja/docs/Web/API/HTMLInputElement/indeterminate) 状態にすることができます: ```svelte
    {#if indeterminate} waiting... {:else if checked} checked {:else} unchecked {/if}
    ``` ## `` 相互に動作する input は、`bind:group` を使用できます。 ([demo](/playground/untitled#H4sIAAAAAAAAE62T32_TMBDH_5XDQkpbrct7SCMGEvCEECDxsO7BSW6L2c227EvbKOv_jp0f6jYhQKJv5_P3PvdL1wstH1Bk4hMSGdgbRzUssFaM9VJciFtF6EV23QvubNRFR_BPUVfWXvodEkdfKT3-zl8Zzag5YETuK6csF1u9ZUIGNo4VkYQNvPYsGRfJF5JKJ8s3QRJE6WoFb2Nq6K-ck13u2Sl9Vxxhlc6QUBIFnz9Brm9ifJ6esun81XoNd860FmtwslYGlLYte5AO4aHlVhJ1gIeKWq92COt1iMtJlkhFPkgh1rHZiiF6K6BUus4G5KafGznCTlIbVUMfQZUWMJh5OrL-C_qjMYSwb1DyiH7iOEuCb1ZpWTUjfHqcwC_GWDVY3ZfmME_SGttSmD9IHaYatvWHIc6xLyqad3mq6KuqcCwnWn9p8p-p71BqP2IH81zc9w2in-od7XORP7ayCpd5YCeXI_-p59mObPF9WmwGpx3nqS2Gzw8TO3zOaS5_GqUXyQUkS3h8hOSz0ZhMESHGc0c4Hm3MAn00t1wrb0l2GZRkqvt4sXwczm6Qh8vnUJzI2LV4vAkvqWgfehTZrSSPx19WiVfFfAQAAA==)): ```svelte ``` > [!NOTE] `bind:group` は、input が同じ Svelte コンポーネント内にある場合にのみ機能します。 ## `` `type="file"` を持つ `` 要素では、`bind:files` を使用して [選択されたファイルの `FileList`](https://developer.mozilla.org/ja/docs/Web/API/FileList) を取得できます。プログラムでファイルを更新する場合、常に `FileList` オブジェクトを使用する必要があります。現在、`FileList` オブジェクトは直接作成できないため、新しい [`DataTransfer`](https://developer.mozilla.org/ja/docs/Web/API/DataTransfer) オブジェクトを作成し、そこから `files` を取得する必要があります。 ```svelte ``` `FileList` オブジェクトも変更できないため、例えばリストから単一のファイルを削除したい場合は、新しい `DataTransfer` オブジェクトを作成し、保持したいファイルを追加する必要があります。 > [!NOTE] `DataTransfer` はサーバーサイドの JS ランタイムでは利用できない場合があります。`files` にバインドされた state を未初期化のままにしておくことで、コンポーネントがサーバーサイドレンダリングされる際の潜在的なエラーを防ぐことができます。 ## `` の値のバインディングは、選択された ` ``` ` ``` ## `