00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Sintassi Base

Struttura di un Componente .svelte

Ogni componente Svelte è un file con estensione .svelte composto da tre sezioni opzionali: script, markup (template) e style.

<script>
  // Logica JavaScript/TypeScript
  let messaggio = $state('Ciao, Svelte!');
</script>

<!-- Markup HTML (template) -->
<h1>{messaggio}</h1>

<style>
  /* CSS con scope automatico */
  h1 {
    color: #ff3e00;
    font-size: 2rem;
  }
</style>

L’ordine delle sezioni non è obbligatorio, ma la convenzione è: <script>, markup, <style>.

La sezione script

La sezione <script> contiene la logica del componente. Qui si dichiarano variabili, si importano moduli e si definiscono funzioni.

<script>
  import { onMount } from 'svelte';
  import Header from '$lib/components/Header.svelte';

  // Variabili di stato (Svelte 5)
  let contatore = $state(0);
  let nome = $state('');

  // Variabili normali (non reattive)
  const API_URL = 'https://api.example.com';

  // Funzioni
  function incrementa() {
    contatore++;
  }

  // Lifecycle
  onMount(() => {
    console.log('Componente montato');
  });
</script>

Il markup (template)

Il markup è puro HTML arricchito con la sintassi di Svelte per espressioni, binding, blocchi logici e direttive.

<header>
  <h1>La mia app</h1>
</header>

<main>
  <p>Benvenuto, {nome}!</p>
  <button onclick={incrementa}>Clicca</button>
</main>

<footer>
  <p>&copy; 2026</p>
</footer>

La sezione style

Gli stili sono scoped al componente per default: le regole CSS si applicano solo al markup di quel componente, non ai componenti figli o al resto della pagina.

<style>
  /* Questo p è SOLO per i <p> di questo componente */
  p {
    color: navy;
    line-height: 1.6;
  }

  /* Classi locali */
  .evidenziato {
    background: yellow;
    padding: 0.2rem 0.5rem;
  }
</style>

Espressioni nel Markup

Interpolazione di variabili

Usa le parentesi graffe {} per inserire espressioni JavaScript nel markup:

<script>
  let nome = $state('Luca');
  let eta = $state(28);
  let items = $state(['Mela', 'Banana', 'Arancia']);
</script>

<!-- Variabile semplice -->
<p>Ciao, {nome}!</p>

<!-- Espressione calcolata -->
<p>L'anno prossimo avrai {eta + 1} anni</p>

<!-- Metodi su stringhe/array -->
<p>{nome.toUpperCase()}</p>
<p>Hai {items.length} frutti</p>

<!-- Operatore ternario -->
<p>{eta >= 18 ? 'Maggiorenne' : 'Minorenne'}</p>

<!-- Template literal -->
<p>{`${nome} ha ${eta} anni`}</p>

Espressioni in attributi HTML

<script>
  let url = $state('https://svelte.dev');
  let attivo = $state(true);
  let colore = $state('#ff3e00');
</script>

<!-- Attributo con espressione -->
<a href={url}>Link</a>

<!-- Attributo con shorthand (nome variabile = nome attributo) -->
<div id={url}></div>

<!-- Attributo condizionale -->
<button disabled={!attivo}>Invia</button>

<!-- Stile inline dinamico -->
<p style="color: {colore}">Testo colorato</p>
<p style:color={colore}>Alternativa con direttiva style</p>

<!-- Classe condizionale -->
<div class:attivo>Sono attivo?</div>
<div class:evidenziato={eta > 18}>Evidenziato se maggiorenne</div>

Spread di attributi

<script>
  let inputProps = $state({
    type: 'email',
    placeholder: 'La tua email',
    required: true
  });
</script>

<!-- Tutti gli attributi dall'oggetto -->
<input {...inputProps} />

Variabili Reattive in Svelte 5

In Svelte 5, la reattività è esplicita tramite le runes:

<script>
  // $state: crea una variabile reattiva
  let contatore = $state(0);

  // Oggetti reattivi - la reattività è profonda (deep)
  let utente = $state({
    nome: 'Mario',
    eta: 30,
    indirizzo: {
      citta: 'Roma'
    }
  });

  // Array reattivi
  let lista = $state(['primo', 'secondo']);

  function aggiungi() {
    // Push funziona direttamente! (in Svelte 4 serviva lista = [...lista, 'nuovo'])
    lista.push('nuovo');
  }

  function aggiornaCitta() {
    // Mutazione profonda reattiva
    utente.indirizzo.citta = 'Milano';
  }
</script>

<p>Contatore: {contatore}</p>
<p>Utente: {utente.nome} da {utente.indirizzo.citta}</p>
<p>Lista: {lista.join(', ')}</p>

Confronto con Svelte 4

<!-- Svelte 4: ogni variabile let è automaticamente reattiva -->
<script>
  let contatore = 0;
  let lista = ['primo'];

  function aggiungi() {
    // In Svelte 4 serviva riassegnare per triggerare la reattività
    lista = [...lista, 'nuovo'];
    // lista.push('nuovo') NON triggerava aggiornamenti in Svelte 4!
  }
</script>

<!-- Svelte 5: reattività esplicita con $state -->
<script>
  let contatore = $state(0);
  let lista = $state(['primo']);

  function aggiungi() {
    // In Svelte 5 le mutazioni funzionano direttamente
    lista.push('nuovo');
  }
</script>

HTML Dinamico

Rendering di HTML raw

Quando hai bisogno di inserire HTML non-escaped, usa il tag speciale {@html}:

<script>
  let contenutoHTML = $state('<strong>Testo in grassetto</strong> e <em>corsivo</em>');
</script>

<!-- ATTENZIONE: non usare con input dell'utente (rischio XSS) -->
{@html contenutoHTML}

Tag di debug

Per il debug in fase di sviluppo:

<script>
  let contatore = $state(0);
  let utente = $state({ nome: 'Test' });
</script>

<!-- Logga nel devtools quando i valori cambiano -->
{@debug contatore, utente}

<p>{contatore}</p>

Costanti nel markup

{@const area = larghezza * altezza}
<p>L'area è {area}</p>

Nota: {@const} funziona solo all’interno di blocchi logici come {#each} o {#if}.

CSS Scoped

Come funziona

Svelte aggiunge automaticamente una classe univoca (come .svelte-1a2b3c) a ogni elemento del componente e ai selettori CSS, rendendo gli stili locali:

<!-- Questo componente -->
<p class="messaggio">Ciao</p>

<style>
  .messaggio { color: blue; }
</style>

<!-- Viene compilato in qualcosa come: -->
<!-- <p class="messaggio svelte-xyz123">Ciao</p> -->
<!-- .messaggio.svelte-xyz123 { color: blue; } -->

Stili globali con :global()

Per applicare stili che escono dallo scope del componente:

<style>
  /* Solo per questo componente */
  p { color: blue; }

  /* Globale: si applica ovunque */
  :global(body) {
    margin: 0;
    font-family: system-ui;
  }

  /* Classe globale dentro un selettore locale */
  div :global(.highlight) {
    background: yellow;
  }
</style>

Direttive class: e style:

<script>
  let attivo = $state(false);
  let colore = $state('red');
  let dimensione = $state(16);
</script>

<!-- Classe condizionale -->
<div class:attivo>Toggle</div>
<div class:attivo={contatore > 5}>Condizionale</div>

<!-- Classe con nome diverso dalla variabile -->
<div class:bg-rosso={errore}>Errore</div>

<!-- Stile inline reattivo -->
<p style:color={colore} style:font-size="{dimensione}px">
  Testo stilizzato
</p>

<!-- Stile con !important -->
<p style:color|important={colore}>Priorità alta</p>

<style>
  .attivo {
    font-weight: bold;
    color: green;
  }
  .bg-rosso {
    background: red;
    color: white;
  }
</style>

Componenti nel Markup

Importazione e uso

<script>
  import Bottone from '$lib/components/Bottone.svelte';
  import Card from '$lib/components/Card.svelte';
</script>

<!-- I componenti iniziano con la lettera maiuscola -->
<Bottone testo="Clicca qui" />
<Card titolo="La mia card">
  <p>Contenuto della card</p>
</Card>

Componenti dinamici

<script>
  import Rosso from './Rosso.svelte';
  import Verde from './Verde.svelte';
  import Blu from './Blu.svelte';

  const componenti = { rosso: Rosso, verde: Verde, blu: Blu };
  let selezione = $state('rosso');
</script>

<!-- svelte:component per rendering dinamico (Svelte 4) -->
<svelte:component this={componenti[selezione]} />

<!-- In Svelte 5, puoi usare direttamente una variabile -->
{@const Componente = componenti[selezione]}
<Componente />

Elementi Speciali di Svelte

<!-- Accesso alla finestra del browser -->
<svelte:window on:keydown={handleKeydown} bind:scrollY={y} />

<!-- Accesso al body -->
<svelte:body on:mouseenter={handleMouseenter} />

<!-- Accesso al document -->
<svelte:document on:visibilitychange={handleVisibility} />

<!-- Head HTML (per meta tag, title, ecc.) -->
<svelte:head>
  <title>La mia pagina</title>
  <meta name="description" content="Descrizione pagina" />
</svelte:head>

Best Practice

  1. Mantieni i componenti piccoli: se un componente supera le 100-150 righe, valuta di dividerlo
  2. Ordine delle sezioni: <script>, markup, <style> per consistenza
  3. Usa TypeScript: <script lang="ts"> per type safety
  4. Evita {@html} con input non fidati per prevenire attacchi XSS
  5. Preferisci class: alle espressioni ternarie per le classi condizionali
  6. Nomina i file con PascalCase: MioComponente.svelte per distinguerli dagli elementi HTML