Werte und JavaScript-Ausdrücke werden in Svelte mit geschweiften Klammern im Markup eingebunden — eine Syntax, die JSX-erfahrenen Entwicklern sofort vertraut ist. Dieser Artikel zeigt die Grundlagen: Werte ausgeben, Attribute setzen, Boolean-Verhalten, automatisches Escaping gegen XSS und wie man in Texten ein literales { schreibt.

Werte ausgeben

Jeder Ausdruck zwischen { und } im Markup wird zur Render-Zeit ausgewertet:

svelte Werte und Ausdrücke
<script>
    let name = $state('Anna');
    let age = $state(30);
</script>

<p>Hallo, {name}!</p>
<p>Alter: {age}</p>
<p>Geboren: {2026 - age}</p>
<p>Vollerwachsen: {age >= 18 ? 'Ja' : 'Nein'}</p>
<p>Großgeschrieben: {name.toUpperCase()}</p>

In den Klammern sind nur Ausdrücke erlaubt — also alles, was einen Wert ergibt. Anweisungen wie if, for oder let funktionieren dort nicht. Für Bedingungen und Schleifen gibt es eigene Block-Syntax (siehe {#if} und {#each}).

Attribute mit dynamischen Werten

Attribute lassen sich genauso mit Klammern setzen:

svelte Dynamische Attribute
<script>
    let user = { name: 'Anna', avatarUrl: '/avatars/anna.jpg' };
    let buttonClass = 'btn btn-primary';
</script>

<img src={user.avatarUrl} alt={user.name} />
<button class={buttonClass}>Klick</button>
<a href={`/users/${user.id}`}>Profil</a>

Statische Werte stehen wie üblich in Anführungszeichen (alt="Avatar"), dynamische in geschweiften Klammern.

Attribute-Shorthand

Wenn der Wert exakt den Attribut-Namen hat, gibt es eine Kurzform:

svelte Shorthand
<!-- Lange Form -->
<img src={src} alt={alt} />

<!-- Shorthand -->
<img {src} {alt} />

Spread-Attribute

Bei Wrapper-Elementen lässt sich ein Objekt mit allen Attributen via Spread setzen:

svelte Spread
<script>
    const inputProps = {
        type: 'email',
        placeholder: 'name@example.com',
        required: true,
    };
</script>

<input {...inputProps} />

Funktioniert sowohl bei HTML-Elementen als auch bei Komponenten.

Boolean-Attribute

Bei Boolean-HTML-Attributen reicht der Attribut-Name allein — gleichbedeutend mit attr={true}:

svelte Booleans
<input type="checkbox" checked />          <!-- true -->
<input type="checkbox" checked={false} />  <!-- false -->
<input type="checkbox" checked={isOn} />   <!-- dynamisch -->

<button disabled={loading}>Speichern</button>

Bei false setzt Svelte das Attribut gar nicht ans DOM-Element — was dem HTML-Standard entspricht.

Automatisches HTML-Escaping

Werte, die mit {expression} ausgegeben werden, werden automatisch HTML-escaped — das schützt zuverlässig vor XSS-Angriffen:

svelte Escaping in Aktion
<script>
    let userInput = '<script>alert("xss")</script>';
</script>

<!-- Wird als Text gerendert, NICHT als Script ausgeführt -->
<p>{userInput}</p>

Das gerenderte HTML enthält wörtlich &lt;script&gt;... — kein ausführbarer Code.

Wenn du bewusst HTML rendern willst, gibt es das {@html ...}-Tag (siehe Special Tags). Vorsicht: Damit fällt der XSS-Schutz weg — nur mit vertrauenswürdigen Quellen verwenden.

Geschweifte Klammern als Text

Wenn { oder } im sichtbaren Text vorkommen sollen (z. B. in Code-Beispielen oder Templates), gibt es zwei Wege:

svelte Wörtliche Klammern
<!-- HTML-Entities -->
<p>Ein Set: &lbrace;1, 2, 3&rbrace;</p>

<!-- String-Literal -->
<p>{'{ Beispiel }'}</p>

In Code-Blöcken (Markdown via <pre> oder ähnlich) ist die Variante mit String-Literal robuster.

Reaktivität in Expressions

Werte aus $state, $derived und $props werden automatisch verfolgt — der Compiler weiß, welche Stellen im Markup von welchen Variablen abhängen, und aktualisiert nur die nötigen DOM-Knoten:

svelte Reaktive Updates
<script>
    let count = $state(0);
    let user = $state({ name: 'Anna' });
</script>

<p>Count: {count}</p>
<p>User: {user.name}</p>
<button onclick={() => count++}>+1</button>

Beim Klick aktualisiert sich nur der Text in <p>Count: ...</p> — nicht der gesamte Block.

Mehrzeilige Ausdrücke

Komplexe Ausdrücke gehen, sind aber meistens lesbarer als $derived-Werte ausgelagert:

svelte − Schwer lesbar
<p>
    {users.filter((u) => u.active)
        .map((u) => u.name)
        .sort()
        .join(', ')}
</p>
svelte + Mit $derived
<script>
    let users = $state([...]);

    let activeNames = $derived(
        users
            .filter((u) => u.active)
            .map((u) => u.name)
            .sort()
            .join(', ')
    );
</script>

<p>{activeNames}</p>

Vorteil: Der Wert ist memoiziert und das Markup bleibt aufgeräumt.

Häufige Stolperfallen

null und undefined. Werden als leerer String gerendert — keine Fehler, aber manchmal überraschend.

0 und leere Strings in Bedingungen.

svelte − 0 wird gerendert
{users.length && <UserList users={users} />}

In Svelte gilt das gleiche wie in JSX: Bei leerer Liste rendert die 0. Stattdessen {#if} nutzen oder explizit > 0-Vergleich.

Funktionsaufrufe ohne Klammern. {getName} gibt die Funktion als Text aus (function getName() {…}). Mit Klammern: {getName()}.

Anführungszeichen-Mix bei Attributen. Auch das klassische HTML-Pattern mit String-Interpolation in Attributwerten funktioniert in Svelte:

svelte Zwei Schreibweisen für dasselbe Attribut
<!-- Klammer im String-Attribut -->
<a href="/users/{id}">Profil</a>

<!-- Template-String in Klammern (oft lesbarer) -->
<a href={`/users/${id}`}>Profil</a>

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Template-Syntax

Zur Übersicht