Actions sind Sveltes Mechanismus, um eigenes Verhalten an ein DOM-Element zu hängen. Du schreibst eine ganz normale Funktion und attachst sie mit use:meineFunktion={...} an ein HTML-Element — Svelte ruft sie auf, sobald das Element im DOM landet, und gibt dir die Möglichkeit, beim Verschwinden wieder aufzuräumen. Klassische Anwendungsfälle: Drittanbieter-Bibliotheken integrieren, Tooltips bauen, Klick-außerhalb-Erkennung, Focus-Management. Dieser Artikel erklärt das Grundprinzip.

Wofür Actions?

Komponenten haben ein eigenes Mounting-Lifecycle (onMount, onDestroy, $effect). Aber manchmal willst du Verhalten an einzelne DOM-Elemente hängen — wiederverwendbar, ohne ständig dieselben Listener-Setups zu kopieren.

Drei typische Beispiele:

  • Tooltip: Beim Hover soll ein kleines Popup erscheinen — gleicher Code an dutzenden Buttons.
  • Klick außerhalb: Ein Dropdown soll sich schließen, wenn der Nutzer woanders klickt.
  • Library-Integration: Eine Datepicker- oder Editor-Library braucht ein Element, an das sie sich hängt.

Statt jedes Mal bind:this, onMount, Listener-Setup, onDestroy zu schreiben, packst du das in eine Action — und benutzt sie überall mit einem einzigen use:.

Die einfachste Action

svelte Hello-World-Action
<script>
    function logMount(node) {
        console.log('Element gemountet:', node);
    }
</script>

<div use:logMount>Hallo</div>

Was hier passiert:

  • logMount ist eine normale Funktion, die als erstes Argument den DOM-Knoten bekommt.
  • use:logMount an einem Element ruft die Funktion auf, sobald dieses Element im DOM ist.
  • Du musst nichts importieren, kein Lifecycle-Hook, kein bind:this. Action und Element sind zusammengeführt.

Cleanup mit $effect

Realistischere Actions wollen beim Mount etwas einrichten und beim Unmount wieder aufräumen — typisch Listener oder Observer. Dafür nutzt man innerhalb der Action $effect:

svelte Listener mit Cleanup
<script>
    function logClicks(node) {
        $effect(() => {
            function handle() {
                console.log('Klick auf', node.tagName);
            }
            node.addEventListener('click', handle);

            return () => node.removeEventListener('click', handle);
        });
    }
</script>

<button use:logClicks>Klick mich</button>

Schritt für Schritt:

  1. logClicks wird beim Mount aufgerufen, mit dem <button>-Knoten.
  2. $effect registriert den Listener.
  3. Wenn der Button später aus dem DOM verschwindet, läuft die Cleanup-Funktion und entfernt den Listener wieder.

Mit Parameter

Actions können Daten von außen entgegennehmen — über das gleiche use:-Konstrukt:

svelte Parameter übergeben
<script>
    function autoFocus(node, options = { delay: 0 }) {
        $effect(() => {
            const id = setTimeout(() => node.focus(), options.delay);
            return () => clearTimeout(id);
        });
    }
</script>

<input use:autoFocus={{ delay: 200 }} />

{ delay: 200 } wird als zweites Argument an autoFocus durchgereicht. Wie auf Parameter-Updates reagiert wird (also wenn sich der Wert während der Lebenszeit ändert), zeigt der Artikel Action-Parameter & Updates.

Mehrere Actions am selben Element

Du kannst beliebig viele Actions am gleichen Element kombinieren — use: lässt sich mehrfach setzen:

svelte Mehrfach-Use
<button use:autoFocus={{ delay: 100 }} use:logClicks use:tooltip={{ text: 'Speichern' }}>
    Speichern
</button>

Jede Action läuft unabhängig, jede räumt selbst hinter sich auf. Genau das macht sie wiederverwendbar und kombinierbar.

Wichtige Eigenschaften

EigenschaftVerhalten
Läuft im SSRNein. Actions sind eine Browser-Sache.
Läuft pro Element-MountGenau einmal pro Mount-Vorgang.
Reaktivität auf ParameterNur in $effect innerhalb der Action.
CleanupÜber die Cleanup-Rückgabe in $effect (oder destroy() im Legacy-Stil).
Mehrfach pro ElementJa, mit mehreren use:.
Action vs. KomponenteAction: hängt Verhalten an existierendes Element. Komponente: rendert eigenes Markup.

Typische Anwendungsfälle

  • Tooltips — bei Hover ein Popup einblenden.
  • Klick-außerhalb-Erkennung — Dropdowns, Modals.
  • Focus-Management — Focus-Trap, Auto-Focus, Tab-Order.
  • Drag-and-Drop — Mouse-/Pointer-Listener am Drag-Handle.
  • Lazy-Loading — IntersectionObserver am Element.
  • Bibliotheks-Integration — Datepicker, Tagify, Quill, Mapbox usw. brauchen ein DOM-Element zum Initialisieren.
  • Long-press / Swipe — Geste-Erkennung.
  • Auto-Resize von Textareas — Content-fit per scrollHeight.

Vertieft im Artikel Praxis-Actions.

Action vs. Komponente — wann was?

Beide kapseln wiederverwendbares Verhalten, aber mit unterschiedlichem Fokus:

SituationEmpfehlung
Verhalten an einem bestehenden ElementAction
Eigenes Markup mit eigener StrukturKomponente
An mehreren verschiedenen Element-Typen einsetzbarAction
Hat eigenen sichtbaren UI-AnteilKomponente
Drittanbieter-Library, die ein Element bekommtAction
Komplexe State-Logik mit eigenem MarkupKomponente

Faustregel: Wenn du nur Verhalten und keine Struktur lieferst, ist eine Action die richtige Wahl.

Interessantes

Action im Top-Level eines .ts-Modul direkt aufrufen.

Actions sind Funktionen, die Svelte beim Mount aufruft — du rufst sie nicht selbst auf. use:meineAction ist der Aufruf.

onMount/onDestroy innerhalb einer Action verwenden.

Lifecycle-Hooks gehören zur Komponente. In Actions arbeitest du mit $effect.

Vergessenes Cleanup.

Wenn deine Action Listener oder Observer registriert, ohne sie zu entfernen, leckt jeder Mount Ressourcen. Cleanup-Rückgabe in $effect ist Pflicht.

Mit node.parentElement arbeiten zu früh.

Beim ersten Aufruf der Action ist das Element zwar im DOM, aber Layout und Geschwister sind je nach Render-Phase noch in Bewegung. Wer auf Eltern-Größen oder -Positionen angewiesen ist, schreibt das in $effect und nicht ins Action-Top-Level.

Vergessen, dass Actions im SSR übersprungen werden.

Code in einer Action läuft nur im Browser. Server-spezifische Logik gehört woanders hin (z. B. in eine load-Funktion).

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Actions

Zur Übersicht