# Svelte als Frontend-Technologie

Svelte ist kein klassisches Framework – es ist ein eleganter Kompiler für das Frontend. Statt virtuellen DOM zu jonglieren, schreibt Svelte reaktiven Code direkt in optimiertes JavaScript. Das ist schnell, leichtgewichtig und so intuitiv, dass man fast vergisst, wie komplex moderne Webentwicklung eigentlich ist.

In diesem Kapitel werden die Stärken und Schwächen von Svelte 5 aufgezeigt.

# Svelte in a Nutshell

Svelte ist ein modernes Frontend-Framework, das sich durch seinen innovativen, compilerbasierten Ansatz von anderen Bibliotheken wie React oder Vue abhebt. Es verspricht eine elegante, minimalistische und leistungsstarke Möglichkeit, Webanwendungen zu erstellen. Dabei gehen sowohl die Entwickler als auch die Community mit Begeisterung und kritischer Auseinandersetzung an die Sache heran.

### Entwicklerperspektive und Community-Erfahrungen

Die Entwickler hinter Svelte haben bewusst einen Weg gewählt, der sich von etablierten Frameworks wie React oder Vue abhebt. Statt auf komplexe Laufzeit-Mechanismen zu setzen, erfolgt die Optimierung bereits im Kompilierungsprozess – ein Ansatz, der sich als besonders performant erweist. Viele Entwickler schätzen an Svelte vor allem:

- <span class="s1">**Intuitive und elegante Syntax:**</span>   
    Die enge Verknüpfung von HTML, CSS und JavaScript in einer Komponente sorgt für übersichtlichen Code, der sich schnell lesen und warten lässt.
- <span class="s1">**Minimale Boilerplate:**</span>   
    Die integrierte Reaktivität reduziert den Code auf das Wesentliche, was insbesondere bei der Entwicklung von komplexen Anwendungen ein echter Gewinn ist.
- <span class="s1">**Exzellente Performance:**</span>   
    Durch die Voraboptimierung entfällt der typische Overhead, den man bei Frameworks mit Virtual DOM häufig vorfindet.

Ein einfaches Beispiel einer Svelte-Komponente illustriert dies:

```
<script>
  let count = $state(0);
</script>

<button onclick={() => count++}>
  Klicks: {count}
</button>
```

Hier zeigt sich, wie nahtlos Logik, Markup und Styling zusammengeführt werden können – ganz ohne das typische „boilerplate“ Gedöns, das man aus anderen Frameworks kennt.

### Kritische Stimmen und Herausforderungen

Trotz aller Vorteile gibt es auch kritische Stimmen: Der Wegfall des Virtual DOM und der Paradigmenwechsel hin zu einer Kompilierungszeit-Optimierung können anfangs ungewohnt sein. Ein weiterer Nachteil, den ich persönlich erlebt habe, ist die mangelnde Vertrautheit von Sprachmodellen (wie etwa ChatGPT) mit der Svelte 5 Syntax.

### Svelte vs. React/Vue – Der Unterschied

Während React und Vue weitgehend auf virtuelle DOM-Differenzierung und Laufzeitoptimierung setzen, geht Svelte einen anderen Weg. Die Unterschiede lassen sich wie folgt zusammenfassen:

- **Kompilierungsansatz**:  
    Svelte kompiliert die Komponenten bereits zur Build-Zeit in hochoptimierten JavaScript-Code, wodurch der Overhead zur Laufzeit minimiert wird.
- **Reaktivität**:   
    Anstatt eine eigene State-Management-Bibliothek oder umfangreiche API-Aufrufe zu benötigen, ist Reaktivität bei Svelte direkt in die Sprache integriert. Das macht den Code oft kürzer und verständlicher.
- **Syntax und Integration**:  
    Svelte kombiniert HTML, CSS und JavaScript in einer einzigen Komponente, was den Entwicklungsprozess vereinfacht und die Wartung erleichtert. Bei React oder Vue sind diese Aspekte oft strikter voneinander getrennt.

### Warum ich jedem einen Blick auf Svelte empfehle und für wen es richtig interessant ist

Svelte übt auf mich als begeisterten Webentwickler und Frontend-Enthusiasten, der selbst regelmäßig Websites baut, eine besondere Anziehungskraft aus. Es ist eine ausgezeichnete Wahl für alle, die Freude an moderner Webentwicklung haben und nach einer eleganten, flexiblen Lösung suchen, die nicht an ein bestimmtes Framework-Ökosystem gebunden ist.

#### Flexibilität und Framework-Agnostik:

Svelte überzeugt insbesondere durch seine ausgeprägte Framework-Agnostik. Diese Eigenschaft macht es zum perfekten Tool, um Frontend-Bibliotheken zu bauen. Im Vergleich zu React und Vue, die eigene Lösungen anbieten, erweist sich Svelte in dieser Hinsicht als äußerst flexibel und leichtgewichtig.

#### Moderne Toolchain

In Kombination mit Tools wie Tailwind CSS und Shadcn-Svelte lassen sich elegante und funktionale Komponentenbibliotheken entwickeln. Diese Kombination aus modernem Styling und flexibler Komponentenarchitektur ermöglicht die Erstellung visuell ansprechender und gleichzeitig performanter Websites, Webapps und Frontend-Bibliotheken.

Neben Svelte selbst lohnen sich aus meiner Sicht auch angrenzende Systeme, die den Entwicklungsprozess bereichern:

- <span class="s1">**[Svelte Kit](https://svelte.dev/docs/kit/introduction#What-is-SvelteKit):**</span> Das offizielle Meta-Framework für Svelte, das serverseitiges Rendering und Dateibasiertes Routing ermöglicht.
- <span class="s1">**[Tailwind CSS](https://tailwindcss.com):**</span> Ein modernes Utility-first CSS Framework, das es erlaubt, schnell und konsistent zu stylen.
- <span class="s1">**[Shadcn-Svelte](https://www.shadcn-svelte.com):**</span> Eine Komponentensammlung, die den Aufbau eigener, eleganter Komponentenbibliotheken erleichtert.
- <span class="s1">**[Threlte](https://threlte.xyz):**</span> Für alle, die 3D-Visualisierungen lieben, bietet Threlte.js eine spannende Möglichkeit, Three.js in Svelte-Projekten zu nutzen.
- <span class="s1">**[Strapi](https://strapi.io) (Headless CMS):**</span> Ideal, wenn du ein flexibles Backend benötigst, das sich nahtlos in Svelte-basierte Projekte integrieren lässt.

# Projektsetup mit SvelteKit

SvelteKit ist das offizielle Meta-Framework rund um Svelte. Es bringt alles mit, was moderne Webentwicklung braucht: Dateibasiertes Routing, SSR, API-Routen, Layouts, und eine cleane DX. In diesem Artikel wird Schritt für Schritt erklärt, wie man ein neues Projekt mit <span class="s1">SvelteKit</span> aufsetzt. Dabei werden die Optionen der SvelteKit CLI beleuchtet und sinnvolle Add-ons wie <span class="s1">**TailwindCSS**</span>, <span class="s1">**Prettier**</span>, <span class="s1">**ESLint**</span> sowie der passende <span class="s1">**Adapter**</span> für das Deployment ausgewählt.

#### Voraussetzungen

- Node.js (empfohlen: aktuelle LTS-Version)
- Ein Terminal (z. B. iTerm2, VS Code Terminal)
- Paketmanager, Vorzugsweise <span class="s1">NPM</span>

#### <span class="s1">Projekt erstellen</span>

Initialisiert wird das Projekt mit folgendem Befehl:

```
npx sv create my-sveltekit-project
```

`my-sveltekit-project` kann dabei durch einen beliebigen Projektnahmen ersetzt werden. `npx` muss ggf. je nach verwendetem Package-Manager angepasst werden.

Bei erstmaliger Ausführung wird das CLI-Paket automatisch installiert. Bestätigung erfolgt mit <span class="s1">y</span>.

```
Need to install the following packages:
sv@0.8.1
Ok to proceed? (y) y
```

#### SvelteKit CLI: Optionen im Überblick

Nun wird das Projekt interaktiv konfiguriert.

##### 1. Template-Auswahl

```
Which template would you like?
❯ SvelteKit minimal (barebones scaffolding for your new app)
  SvelteKit demo
  Svelte library
```

- <span class="s1">**SvelteKit minimal**</span>: Reduziertes Grundgerüst für ein eigenes Projekt ohne Beispielcode.
- <span class="s1">**SvelteKit demo**</span>: Enthält Beispielseiten und eine Beispielnavigation.
- <span class="s1">**Svelte library**</span>: Template zur Entwicklung wiederverwendbarer Svelte-Komponenten.

Wir wählen für diese Demonstration SvelteKit minimal.

##### 2. TypeScript-Unterstützung

```
Add type checking with TypeScript?
❯ Yes, using TypeScript syntax
  Yes, using JavaScript with JSDoc comments
  No
```

Empfohlen wird die Verwendung der TypeScript-Syntax, um statische Typüberprüfung und IntelliSense zu nutzen.

##### 3. Erweiterungen im Projektsetup

Nach der Projekterstellung fragt das CLI nach zusätzlichen Tools und Bibliotheken, die dem Projekt hinzugefügt werden sollen. Die Auswahl erfolgt interaktiv über die Leertaste (Mehrfachauswahl möglich). Die Optionen sind:

```
What would you like to add to your project?
❒ prettier          (formatter – https://prettier.io)
❒ eslint            (linter – https://eslint.org)
❒ vitest            (unit testing – https://vitest.dev)
❒ playwright        (e2e testing – https://playwright.dev)
❒ tailwindcss       (CSS utility framework – https://tailwindcss.com)
❒ sveltekit-adapter (adapter for deployment – https://kit.svelte.dev/docs#adapters)
❒ drizzle           (ORM – https://orm.drizzle.team/)
❒ lucia             (auth – https://lucia-auth.com)
❒ mdsvex            (Markdown + Svelte – https://mdsvex.pngwn.io/)
❒ paraglide         (i18n – https://paraglide.dev/)
❒ storybook         (component explorer – https://storybook.js.org)
```

<table id="bkmrk-erweiterung-beschrei"><thead><tr><th>**Erweiterung**

</th><th>**Beschreibung**

</th><th>**Einsatzzweck**

</th></tr></thead><tbody><tr><td>**Prettier**

</td><td>Automatisches Codeformatierungs-Tool. Definiert einheitlichen Stil für z. B. Einrückung, Semikolons.

</td><td>Formatierung &amp; Clean Code

</td></tr><tr><td>**ESLint**

</td><td>Linter zur statischen Analyse von JavaScript/TypeScript-Code. Findet potenzielle Fehler &amp; Stilprobleme.

</td><td>Codequalität und Fehlervorbeugung

</td></tr><tr><td>**Vitest**

</td><td>Schnelles Unit-Testing-Framework, optimiert für Vite und moderne Frontends.

</td><td>Komponententests, Logiktests

</td></tr><tr><td>**Playwright**

</td><td>Framework für End-to-End-Tests. Ermöglicht UI-Tests mit echten Browserinstanzen.

</td><td>Testen von Userflows &amp; Accessibility

</td></tr><tr><td>**TailwindCSS**

</td><td>Utility-first CSS-Framework für schnelles und responsives Styling.

</td><td>Styling über Utility-Klassen

</td></tr><tr><td>**SvelteKit Adapter**

</td><td>Bindeglied zwischen dem Framework und der Zielplattform (z. B. statisches HTML, SSR, Vercel etc.).

</td><td>Deployment-Anpassung

</td></tr><tr><td>**Drizzle**

</td><td>TypeScript-ORM für SQL-Datenbanken mit gutem DX.

</td><td>Datenbankzugriff (PostgreSQL etc.)

</td></tr><tr><td>**Lucia**

</td><td>Authentifizierungs-Framework mit Fokus auf Einfachheit und Sicherheit.

</td><td>Login-Mechanismen, Zugriffskontrolle

</td></tr><tr><td>**mdsvex**

</td><td>Markdown-Präprozessor für Svelte-Komponenten. Kombination von Markdown und Svelte möglich.

</td><td>Content Management, Dokusysteme

</td></tr><tr><td>**Paraglide**

</td><td>Internationalisierungs-Tool mit Compile-Time-Optimierung.

</td><td>Mehrsprachigkeit (i18n)

</td></tr><tr><td>**Storybook**

</td><td>Tool zur Visualisierung und Dokumentation einzelner UI-Komponenten.

</td><td>Komponentenkatalog &amp; Dokumentation

</td></tr></tbody></table>

In diesem Beispiel wählen wir: prettier, eslint, tailwindcss, sveltekit-adapter

##### 4. TailwindCSS Plugins

Wir haben uns im Schritt zuvor entschieden, <span class="s1">**TailwindCSS**</span> in das Projekt einzubinden. TailwindCSS ist ein Utility-first CSS-Framework, das die Gestaltung von Benutzeroberflächen durch vorgefertigte CSS-Klassen stark vereinfacht. Nach Auswahl von <span class="s1">tailwindcss</span> im Add-on-Menü wird abgefragt, welche <span class="s2">**Plugins**</span> integriert werden sollen:

```
tailwindcss: Which plugins would you like to add?
❒ typography (@tailwindcss/typography)
❒ forms     (@tailwindcss/forms)
```

<table id="bkmrk-plugin-beschreibung-" style="width: 100%;"><thead><tr><th style="width: 12.7537%;">**Plugin**

</th><th style="width: 87.2463%;">**Beschreibung**

</th></tr></thead><tbody><tr><td style="width: 12.7537%;">**Typography**

</td><td style="width: 87.2463%;">Stellt sinnvolle Standard-Styles für typografische Inhalte bereit. Eignet sich besonders für Content-lastige Seiten, z. B. Dokumentation oder Blogbeiträge.

</td></tr><tr><td style="width: 12.7537%;">**Forms**

</td><td style="width: 87.2463%;">Vereinheitlicht das Styling von nativen HTML-Formular-Elementen wie <span class="s1">input</span>, <span class="s1">select</span>, <span class="s1">textarea</span> etc. Passt sich automatisch an das Tailwind-Designsystem an.

</td></tr></tbody></table>

Wir wählen beide Plugins aus.

##### 5. Auswahl des SvelteKit Adapters

SvelteKit ist ein Meta-Framework, das Applikationen sowohl statisch als auch serverseitig oder als Hybrid generieren kann. <span class="s1">**Adapter**</span> übernehmen dabei die Aufgabe, die Anwendung für eine bestimmte Zielplattform aufzubereiten (z. B. als statische HTML-Seiten oder als Server-Handler für Vercel, Netlify, Node.js etc.).

Die Auswahl erfolgt im CLI nach Aktivierung des Add-ons `<span class="s1">sveltekit-adapter</span>`:

```
sveltekit-adapter: Which SvelteKit adapter would you like to use?
  auto
  node
❯ static (@sveltejs/adapter-static)
  vercel
  cloudflare-pages
  netlify
```

<table id="bkmrk-adapter-beschreibung"><thead><tr><th>**Adapter**

</th><th>**Beschreibung**

</th><th>**Typ**

</th><th>**Empfohlene Einsatzzwecke**

</th></tr></thead><tbody><tr><td>**auto**

</td><td>Automatische Auswahl anhand der Umgebung. Praktisch für Entwicklung, aber nicht für produktives Deployment empfohlen.

</td><td>auto-detect

</td><td>Nur lokale Nutzung, z. B. für Tests

</td></tr><tr><td>**node**

</td><td>Erstellt ein Node.js-Handler zur Laufzeit, z. B. für Express, Fastify oder Cloud-Server.

</td><td>SSR

</td><td>Eigener Serverbetrieb, z. B. VPS, Docker-Container

</td></tr><tr><td>**static**

</td><td>Exportiert alle Seiten als HTML/CSS/JS. Kein dynamisches Routing, aber sehr performant.

</td><td>SSG (Static Site)

</td><td>GitHub Pages, Netlify, klassische Webserver

</td></tr><tr><td>**vercel**

</td><td>Optimierung für das Vercel-Ökosystem. Deployment erfolgt über Vercel CLI oder GitHub-Integration.

</td><td>Edge-/SSR-ready

</td><td>Hosting über [vercel.com](https://vercel.com)

</td></tr><tr><td>**cloudflare-pages**

</td><td>Unterstützung für Cloudflare Pages, inkl. Worker-Skripte.

</td><td>Edge SSR

</td><td>Deployment auf [pages.cloudflare.com](https://pages.cloudflare.com)

</td></tr><tr><td>**netlify**

</td><td>Adapter mit Funktionen wie Functions, Redirects, SSR via Netlify.

</td><td>Hybrid

</td><td>Deployment auf [netlify.com](https://www.netlify.com)

</td></tr></tbody></table>

Für unser Beispiel wählen wir `static`.

##### 6. Wahl des Paketmanagers

```
Which package manager do you want to install dependencies with?
❯ npm
  yarn
  pnpm
  bun
  deno
```

Die Auswahl erfolgt entsprechend der individuellen Präferenz. `<span class="s1">npm</span>` ist in den meisten Fällen ausreichend.

##### 7. Nächste Schritte nach dem Setup

Nach erfolgreichem Setup wird vom CLI folgender Ablauf vorgeschlagen:

```
cd my-sveltekit-project
git init && git add -A && git commit -m "Initial commit"   # optional
npm run dev -- --open
```

Damit wird der lokale Entwicklungsserver gestartet. Der Zugriff erfolgt typischerweise unter <span class="s1">[http://localhost:5173](http://localhost:5173)</span>.

#### Projektstruktur nach dem Setup

Nach erfolgreichem Setup mit der SvelteKit CLI liegt eine vorstrukturierte Projektbasis vor. Diese Struktur ermöglicht den sofortigen Einstieg in die Anwendungsentwicklung, getrennt nach Konfiguration, Komponenten, Routen und Styling.

Ein typisches Grundgerüst (vereinfacht dargestellt):

```
my-sveltekit-project/
├── src/
│   ├── lib/
│   │   └── components/     ← Wiederverwendbare UI-Komponenten
│   ├── routes/             ← Seitenstruktur (basierend auf Datei-Routing)
│   │   └── +page.svelte    ← Startseite (Route: "/")
│   └── app.css             ← TailwindCSS-Einstiegspunkt
├── static/                 ← Öffentliche Assets (z. B. Bilder, favicon)
├── svelte.config.js        ← Zentrale SvelteKit-Konfiguration
├── tailwind.config.cjs     ← TailwindCSS-Konfiguration
├── postcss.config.cjs      ← PostCSS-Integration für Tailwind
├── tsconfig.json           ← TypeScript-Projektdefinition
├── package.json            ← Abhängigkeiten und Skripte
└── vite.config.js          ← Build-Tool-Konfiguration (Vite)
```

<table id="bkmrk-pfad-beschreibung-sr" style="width: 100%;"><thead><tr><th style="width: 25.6189%;">**Pfad**

</th><th style="width: 74.3811%;">**Beschreibung**

</th></tr></thead><tbody><tr><td style="width: 25.6189%;">src/routes/

</td><td style="width: 74.3811%;">Implementierung der Seitenstruktur der Anwendung. Jede Datei oder jeder Ordner stellt eine Route dar.

</td></tr><tr><td style="width: 25.6189%;">src/routes/+page.svelte

</td><td style="width: 74.3811%;">Einstiegspunkt der Anwendung (Startseite, Route <span class="s1">/</span>). Kann sofort bearbeitet werden.

</td></tr><tr><td style="width: 25.6189%;">src/lib/

</td><td style="width: 74.3811%;">Globale Hilfsmittel, z. B. Komponenten, Stores, Services. Nicht Routen-spezifisch.

</td></tr><tr><td style="width: 25.6189%;">src/app.css

</td><td style="width: 74.3811%;">Haupt-Stylesheet. Hier wird TailwindCSS eingebunden (<span class="s1">@tailwind base</span>, <span class="s1">components</span>, <span class="s1">utilities</span>).

</td></tr><tr><td style="width: 25.6189%;">static/

</td><td style="width: 74.3811%;">Enthält öffentlich zugängliche Dateien (z. B. <span class="s1">robots.txt</span>, <span class="s1">favicon.ico</span>, statische Bilder).

</td></tr><tr><td style="width: 25.6189%;">svelte.config.js

</td><td style="width: 74.3811%;">Konfiguriert Adapter, Preprocessing, Pfade etc.

</td></tr><tr><td style="width: 25.6189%;">tailwind.config.cjs

</td><td style="width: 74.3811%;">Definiert Tailwind-Themes, Plugins und Pfade zur Content-Erkennung.

</td></tr><tr><td style="width: 25.6189%;">tsconfig.json

</td><td style="width: 74.3811%;">Konfiguriert das Verhalten des TypeScript-Compilers.

</td></tr></tbody></table>

# Grundkonzepte von Svelte 5

Svelte 5 führt mit den sogenannten *Runes* eine neue, klare Art ein, mit Reaktivität umzugehen.

- <span class="s1">$state()</span> für reaktiven Zustand
- <span class="s1">$derived()</span> für abgeleitete Werte
- <span class="s1">$effect()</span> für Nebenwirkungen (z. B. DOM-Manipulation)
- <span class="s1">$props()</span> für Props-Zugriff
- <span class="s1">$bindable()</span> für zwei-Wege-Bindung

Beispiel:

```
<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>

<button onclick={() => count++}>
	Doppelt: {doubled}
</button>
```

<p class="callout info">Keine useState-Calls, keine riesige API – nur schlankes HTML &amp; JavaScript.</p>

TODO:

- Dateibenennung
- Import/Export von Komponenten/Modulen
- *Runes* im Detail
- TypeScript-Support

# Styling & UX mit Tailwind CSS

Tailwind CSS passt hervorragend zu Svelte. Es erlaubt schnelles Prototyping, konsistentes Design und volle Kontrolle direkt im Markup.

```
<button class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded">
  Klick mich
</button>
```

TODO:

- Verweis auf Installation mit SvelteKit
- Dev- vs. Build-Mode

# Beispielaufgabe: Vier Gewinnt

In dieser Beispielaufgabe entwickeln wir eine einfache Webanwendung mit <span class="s3">**SvelteKit**</span>, die das klassische Spiel „Vier Gewinnt“ als lokale Zwei-Spieler-Variante umsetzt. Diese Version enthält ausschließlich Frontend-Logik und basiert auf dem <span class="s3">**Static Adapter**</span> von SvelteKit. Sie bildet die Grundlage für die spätere Erweiterung um eine Multiplayer-Funktion mit Datenbankanbindung im nächsten Kapitel.

### Zielsetzung

Ziel dieser Aufgabe ist es, ein funktionierendes Spiel zu bauen, das komplett im Browser läuft, keine Verbindung zu einem Server benötigt und als statische Website bereitgestellt werden kann. Die Umsetzung soll die Stärken von <span class="s3">**Svelte**</span> bei der Entwicklung interaktiver Komponenten demonstrieren und gleichzeitig ein übersichtliches Projekt mit nachvollziehbarer Struktur liefern.

### Projektgrundlage

Wir starten mit der Initialisierung eines neuen SvelteKit-Projekts. Dafür verwenden wir das SvelteKit CLI.

```
npm create svelte@latest vier-gewinnt-frontend
```

Im Setup wählen wir das SvelteKit minimal Setup, aktivieren TypeScript, ESLint, Prettier, Tailwind CSS und wir installieren wir den Static Adapter. Eine genauere Dokumentation des CLI findest du in dem Artikel [Projektsetup mit SvelteKit](https://wiki.kleinform.at/books/advanced-web-technologies-wiki-zum-mastermodul/page/projektsetup-mit-sveltekit "Projektsetup mit SvelteKit").

Um die Anwendung während der Entwicklung im Browser zu testen, starten wir den Entwicklungsserver:

```
npm run dev --open
```

### Projektstruktur

Der Einstiegspunkt für unsere Anwendung befindet sich in der Datei `src/routes/+page.svelte`.

In dieser Komponente schreiben wir sowohl die Spiellogik als auch das HTML-Markup und das grundlegende Styling direkt in einer Datei. Für diese Frontend-Version verzichten wir bewusst auf eine Aufteilung in mehrere Komponenten – das reduziert vorerst die Komplexität.

Im Projektverzeichnis befinden sich zahlreiche Dateien und Ordner, von denen für diese Aufgabe nur wenige eine Rolle spielen:

```
vier-gewinnt-frontend/
├── src/
│   ├── app.css
│   └── routes/
│       ├── +layout.svelte     ← gemeinsames Layout aller Seiten
│       ├── +layout.ts         ← legt fest, dass das Projekt prerenderbar ist
│       └── +page.svelte       ← Hauptdatei mit Spiellogik und UI
├── svelte.config.js
├── package.json
└── ...
```

#### Die Rolle von +layout.svelte

Die Datei `<span class="s2">+layout.svelte</span>` ist bei SvelteKit der Standardort für gemeinsame Layouts, die auf allen Seiten einer Route (hier: `<span class="s2">/</span>`) angezeigt werden sollen. In unserem Fall nutzen wir sie, um globale Styles (`<span class="s2">app.css</span>`) einzubinden und das allgemeine Layout der Seite zu definieren – z. B. zentrierte Inhalte, Container-Breiten oder Hintergrundfarben.

```
<script lang="ts">
	import '../app.css';
	let { children } = $props();
</script>

<div class="container mx-auto p-8">
	{@render children()}
</div>
```

### Spiellogik

In der Datei (`<span class="s2">src/routes/+page.svelte</span>`) befindet sich unsere Haupt-Anwendung. Hier arbeiten wir mit mehreren zentralen Konzepten, die typisch für die Entwicklung mit <span class="s1">**SvelteKit**</span> sind. Anhand des Spiels lernen wir grundlegende Elemente kennen, mit denen sich interaktive Webanwendungen effizient umsetzen lassen.

#### Komponentenbasiertes Markup

Der HTML-Teil innerhalb der Datei ist direkt mit dem TypeScript-Code verknüpft. Das Markup beschreibt dabei nicht nur die Oberfläche, sondern ist <span class="s1">**reaktiv**</span> an die zugrunde liegende Logik gebunden – Änderungen im Zustand führen unmittelbar zu visuellen Updates.

#### Reaktive Zustände mit $state()

SvelteKit 5 bringt mit `<span class="s2">$state()</span>` ein vereinfachtes Modell für lokale Zustände innerhalb von Komponenten. In unserem Beispiel werden darüber folgende Variablen verwaltet:

- das aktuelle Spielfeld (<span class="s1">grid</span>)
- der aktive Spieler (<span class="s1">currentPlayer</span>)
- ein möglicher Gewinner (<span class="s1">winner</span>)

Wenn sich diese Werte ändern, wird das DOM automatisch aktualisiert – ganz ohne manuelle DOM-Manipulation oder explizite „set“-Funktionen.

#### each-Blöcke für dynamisches Rendering

Zur Darstellung des Spielfelds nutzen wir den <span class="s2">each</span>-Block von Svelte. Damit lassen sich Arrays direkt im Template durchlaufen. In unserem Fall verwenden wir verschachtelte <span class="s2">each</span>-Blöcke, um die zweidimensionale Grid-Struktur darzustellen:

```
{#each grid as row}
  {#each row as cell}
    <!-- einzelne Zelle -->
  {/each}
{/each}
```

Diese Technik ist in Svelte besonders elegant, da sie mit minimalem Code dynamische und komplexe Strukturen erlaubt.

#### Bedingte Anzeige mit if

Der <span class="s2">if</span>-Block ermöglicht es, Inhalte abhängig vom Zustand darzustellen. Beispielsweise zeigen wir den Gewinner nur an, wenn das Spiel beendet ist:

```
{#if winner}
  <p>Spieler {winner} hat gewonnen!</p>
{:else}
  <p>Am Zug: Spieler {currentPlayer}</p>
{/if}
```

#### Dateibasierte Routen

Ein weiterer wichtiger Aspekt von SvelteKit ist das <span class="s2">**Dateisystem-basierte Routing**</span>. Jede Datei im Ordner `<span class="s3">src/routes</span>` entspricht automatisch einer URL. In unserem Fall:

- src/routes/+page.svelte<span class="s1"> → </span>/
- <span class="s1">src/routes/+layout.svelte</span> → gemeinsames Layout für alle Unterseiten

Dieses Routing-Prinzip reduziert die Komplexität im Vergleich zu klassischen Router-Konfigurationen erheblich.

#### Empfehlung: Code ansehen &amp; selbst ausprobieren

Ich empfehle, den Code einmal vollständig durchzugehen oder lokal auszuführen, um diese Konzepte selbst auszuprobieren und besser zu verstehen.

👉 [Zum vollständigen Code auf GitLab](https://gitlab.rlp.net/marius.klein2/awt-marius-klein/-/tree/main/beispielaufgaben/vier-gewinnt)

### Build &amp; Deploy

Beim Einsatz des Static Adapters müssen wir SvelteKit explizit mitteilen, dass Seiten <span class="s2">**statisch generiert**</span> werden dürfen. Das geschieht über eine Datei <span class="s3">`+layout.ts`.</span>

```
vier-gewinnt-frontend/
├── src/
│   ├── app.css
│   └── routes/
│       ├── +layout.svelte
│       ├── +layout.ts         ← muss hier erstellt werden
│       └── +page.svelte
├── svelte.config.js
├── package.json
└── ...
```

In der in der <span class="s3">`+layout.ts`</span> müssen wir <span class="s3">export `const prerender = true`</span> setzen:

```
// src/routes/+layout.ts
export const prerender = true;
```

Ohne diese Angabe bleibt SvelteKit im „SSR-Modus“ und erzeugt keine statischen HTML-Dateien beim Build. Für die Frontend-only-Version ist das jedoch notwendig.

Jetzt kann das Projekt gebaut werden:

```
npm run build
```

Der HTML-Code befindet sich danach im Ordner `build` und kann direkt auf einen Webserver geladen werden.

# Exkurs: 3D-Anwendungen im Handumdrehen mit Threlte

```bash
npm install three @threlte/core @threlte/extras
```