# Astro: the component stays static because the client directive is missing

In Astro a component without `client:*` renders to HTML and never hydrates. The events stay dead. Pick the directive from when interactivity is needed.

> Page: https://ui.eneawork.it/blog/astro-client-directive-mancante
> Markdown: https://ui.eneawork.it/blog/astro-client-directive-mancante.md

*2026-11-01*

Risposta breve: senza una direttiva client:*, un componente React, Vue o Svelte dentro Astro viene reso in HTML e mai idratato. Il markup c'è, gli eventi no. Aggiungi la direttiva in base a quando serve l'interattività.

Il tag astrojs conta 752 domande sulla Stack Exchange API al 31 ottobre 2026. Il modello a isole è la causa più frequente di «il componente non risponde». Le cifre del catalogo EneUI, misurate da /api/stats il 1 novembre 2026, sono 111.985 componenti, 1.556 blocchi, 12.808 icone da 1.472 librerie. Ogni comando qui sotto è eseguibile in locale: nessun passaggio richiede un account.

## Le direttive

## Perché l'HTML arriva già finito

Il meccanismo è la compilazione. Astro legge il file .astro a build time e chiede al renderer del framework una stringa HTML. La direttiva client:* è ciò che trasforma quella stringa in un elemento astro-island, con l'URL del componente, quello del renderer e le props serializzate negli attributi. Senza direttiva il nodo esce come HTML puro: nessuno script lo raggiunge, quindi nessun listener viene registrato e nessuno stato esiste. Il componente non è rotto, è una fotografia.

## L'esempio

--- import Counter from "../components/Counter.tsx"; ---

client:only richiede il nome del framework perché Astro non può dedurlo dal file: senza, la build fallisce.

## Come verificarlo

# quante isole contiene davvero l'HTML servito curl -s http://localhost:4321/ | grep -o "<astro-island" | wc -l # quali direttive esistono nel sorgente # (PowerShell: Select-String -Path src/**/*.astro -Pattern "client:") grep -rn "client:" src --include="*.astro"

Il primo comando conta le isole nell'HTML servito, il secondo trova le direttive nel sorgente. Se il conteggio è zero su una pagina che dovrebbe essere interattiva, la causa è nel sorgente. Se è molto più alto di quanto ti aspetti, il problema è l'opposto e costa byte: una tabella con una direttiva per riga diventa una fila di punti di idratazione.

## Cosa non passa attraverso un'isola

Le props devono essere serializzabili. Una funzione passata dal file .astro al componente non attraversa il confine: il componente riceve undefined e l'errore arriva a runtime. Passa dati o definisci il gestore dentro il componente client.

## Quando la correzione non funziona

Se aggiungi la direttiva e l'evento continua a non funzionare, controlla la console: un errore di idratazione annulla il mount dell'isola. Un secondo caso è un componente che dipende da un contesto React creato fuori dall'isola: ogni isola è un albero separato, e il provider deve stare dentro.

Attenzione anche al costo: ogni isola porta il runtime del framework. Dieci isole React sulla stessa pagina significano un runtime caricato una volta, ma dieci punti di idratazione da coordinare. Preferisci una sola isola che contiene l'interazione.

## Quando la correzione tipica peggiora le cose

La correzione che circola è mettere client:load ovunque qualcosa non risponde. Risolve il sintomo e aggiunge due costi. Astro serializza le props dentro l'attributo dell'isola: una lista di quaranta righe con una direttiva per riga produce quaranta isole e quaranta copie dei dati nel documento, che il browser legge e idrata una per una. Il peso dell'HTML cresce, il tempo prima dell'interattività anche, e il problema di partenza era una sola direttiva mancante.

## Il limite di client:visible

Un limite noto di client:visible: l'idratazione dipende da IntersectionObserver. Se l'isola sta dentro un pannello chiuso, un contenitore con altezza zero o un elemento con display:none, non interseca mai il viewport e resta inerte. Non compare un errore, il markup è corretto e il comando non risponde: la diagnosi somiglia di nuovo a una direttiva mancante, e la prima ipotesi sbagliata costa mezz'ora.

## Come prevenirlo

## Dove continuare

Nel catalogo: blocco hero, componenti e blocchi. Le guide: struttura App Router e checklist accessibilità; il confronto: peso di una libreria UI.

## FAQ

### Perché il bottone non risponde al click?

Il componente è stato renderizzato in HTML senza idratazione. Aggiungi la direttiva `client:*` appropriata.

### `client:load` e `client:idle` cambiano l'aspetto?

No. Cambiano quando il JavaScript viene eseguito; l'HTML iniziale è lo stesso, salvo componenti che dipendono dall'interattività per il primo paint.

### Quando serve `client:only`?

Quando il componente non può essere renderizzato sul server: usa il browser, un canvas o una libreria che accede a `window` all'import.

### Perché `client:only` richiede un valore?

Perché Astro non può dedurre il framework dal file in quel caso: scrivi `client:only="react"`.

### Come verifico che l'isola sia idratata?

Guarda nell'HTML l'attributo `astro-island` e nel pannello Network il chunk del framework. Se manca il chunk, la direttiva non è stata applicata.
