onMount ist die wahrscheinlich bekannteste Lifecycle-Funktion in Svelte. Sie führt eine Funktion aus, sobald deine Komponente fertig im DOM gelandet ist — also nach dem ersten Render. Typische Aufgaben: einen Drittanbieter-Initialisieren (Chart, Karte, Editor), eine API abfragen, einen Timer starten oder etwas im echten DOM messen. Dieser Artikel erklärt, wie onMount funktioniert, was beim Server-Side-Rendering passiert, wie Cleanup geht — und wann du in Svelte 5 stattdessen besser $effect nimmst.

Was ist onMount?

Stell dir vor, deine Komponente wird das erste Mal angezeigt. Svelte baut das HTML, hängt es ins DOM, der Browser zeichnet es. Genau in dem Moment, wenn alles fertig ist und der Nutzer die Komponente sehen kann, läuft onMount.

svelte Minimales Beispiel
<script>
    import { onMount } from 'svelte';

    onMount(() => {
        console.log('Komponente ist jetzt im DOM');
    });
</script>

<h1>Hallo</h1>

Wichtig zu verstehen:

  • onMount ist eine Funktion, die du aus dem svelte-Modul importierst.
  • Du übergibst ihr eine Callback-Funktion, die später laufen soll.
  • Der Aufruf von onMount(...) selbst muss im Top-Level des <script> stehen — nicht in einer if- oder setTimeout-Anweisung.

Wann genau läuft onMount?

Der Zeitpunkt ist wichtig, weil viele Probleme daher kommen, dass man ihn missversteht:

  • Nach dem ersten Render im Browser.
  • Nicht beim Server-Side-Rendering (SSR). Wenn deine Seite per SvelteKit auf dem Server gerendert wird, läuft onMount dort nicht. Erst im Browser, nach Hydration.
  • Nur einmal pro Komponenten-Instanz. Wenn die Komponente unmounted und später wieder gemountet wird, läuft sie erneut — aber nicht bei normalen Updates.

Das macht onMount ideal für Aufgaben, die das echte DOM brauchen oder nur einmalig passieren sollen.

Cleanup mit der Rückgabefunktion

Wenn dein onMount etwas startet, was später beendet werden muss — z. B. einen Timer, einen Listener, eine WebSocket-Verbindung — dann gibst du eine Funktion zurück. Svelte führt sie aus, wenn die Komponente entfernt wird.

svelte Timer mit Cleanup
<script>
    import { onMount } from 'svelte';

    let seconds = $state(0);

    onMount(() => {
        const intervalId = setInterval(() => {
            seconds++;
        }, 1000);

        // Cleanup: läuft beim Unmount
        return () => clearInterval(intervalId);
    });
</script>

<p>Sekunden seit Mount: {seconds}</p>

So entsteht keine „Memory-Leak”-Situation, in der ein Timer im Hintergrund weiterläuft, obwohl die Komponente längst weg ist.

async in onMount?

onMount kann eine async-Funktion sein:

svelte Async-onMount
<script>
    import { onMount } from 'svelte';

    let user = $state(null);

    onMount(async () => {
        const res = await fetch('/api/user');
        user = await res.json();
    });
</script>

{#if user}
    <h1>{user.name}</h1>
{:else}
    <p>Lädt …</p>
{/if}

Aber Achtung: Bei einer async-Funktion kannst du keine Cleanup-Funktion zurückgeben. Eine async-Funktion gibt immer ein Promise zurück, nicht eine Funktion. Wenn du Cleanup brauchst, geh so vor:

svelte Cleanup + Async kombiniert
<script>
    import { onMount } from 'svelte';

    let user = $state(null);

    onMount(() => {
        let cancelled = false;

        async function load() {
            const res = await fetch('/api/user');
            if (!cancelled) user = await res.json();
        }

        load();

        return () => { cancelled = true; };
    });
</script>

Erklärung: Die äußere Funktion ist synchron (gibt Cleanup zurück), die innere load-Funktion erledigt das Asynchrone. Die cancelled-Flag verhindert, dass ein verzögertes fetch-Ergebnis noch in eine bereits unmountete Komponente schreibt.

Praxis-Beispiel: Drittanbieter initialisieren

Klassiker — eine Chart-Library, die das Element zur Laufzeit braucht:

svelte Chart.svelte
<script>
    import { onMount } from 'svelte';
    import { Chart } from 'chart.js/auto';

    let { data } = $props();
    let canvas;
    let chartInstance;

    onMount(() => {
        chartInstance = new Chart(canvas, {
            type: 'bar',
            data,
        });

        return () => chartInstance.destroy();
    });
</script>

<canvas bind:this={canvas}></canvas>

Schritt für Schritt:

  1. bind:this={canvas} gibt uns die Referenz auf das <canvas>-Element.
  2. onMount läuft erst, wenn das <canvas> wirklich im DOM hängt — vorher ist der Zugriff sinnlos.
  3. Beim Unmount zerstören wir die Chart-Instanz, damit keine Listener oder Animation-Frames im Hintergrund weiterlaufen.

onMount vs. $effect – wann nimmt man was?

In Svelte 5 mit Runes gibt es eine zweite Möglichkeit für „nach dem Mount”: die Rune $effect (siehe $effect). Beide laufen nach dem ersten Render — die Unterschiede liegen in der Wiederholung und im Tracking.

AspektonMount$effect
Wie oft?Genau einmal pro MountBei jeder Änderung der Abhängigkeiten
Reagiert auf $state?NeinJa (automatisches Tracking)
Cleanupreturn () => …return () => …
Im SSR?NeinNein

Faustregel:

  • „Nur einmal beim Start” -> onMount.
  • „Reagieren, wenn ein Wert sich ändert” -> $effect.

Beide haben ihren Platz — onMount ist klarer, wenn die Initialisierung wirklich nur einmal passieren soll.

Häufige Stolperfallen

onMount in einer Bedingung aufrufen.

svelte − Falsch
<script>
    import { onMount } from 'svelte';
    let { active } = $props();

    if (active) {
        onMount(() => { /* … */ }); // läuft nicht zuverlässig
    }
</script>

Lifecycle-Hooks müssen im Top-Level des <script> stehen. Bedingte Logik gehört innen in den Callback.

onMount mit Cleanup als async vergessen. Wer onMount(async () => { … return () => …; }) schreibt, hat keine Cleanup-Funktion zurückgegeben — sondern ein Promise, das eine Funktion enthält. Cleanup feuert nicht. Lösung: Die äußere Funktion synchron lassen (siehe Abschnitt 04).

Annahme: Läuft auch beim Server-Rendering. Tut es nicht. Wer im SSR-Kontext etwas tun will, nutzt SvelteKit-load-Funktionen oder andere Hooks.

document oder window außerhalb von onMount nutzen. Im Top-Level des Scripts greift dein Code beim SSR auch auf dem Server — wo window und document nicht existieren. Solche Zugriffe gehören in onMount.

svelte − Crash beim SSR
<script>
    const width = window.innerWidth; // crasht auf dem Server
</script>
svelte + Sicher
<script>
    import { onMount } from 'svelte';
    let width = $state(0);

    onMount(() => {
        width = window.innerWidth;
    });
</script>

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Lifecycle

Zur Übersicht