React
Registry privati: token, namespace e installazioni in CI
Come funziona un registry shadcn privato: autenticazione, namespace, scope del token e installazione ripetibile in CI. Con gli errori che si vedono davvero.
In sintesi
- Un registry privato è un URL più un token: il CLI non conosce il concetto di team.
- Il namespace separa le fonti nel `components.json` e rende leggibile l’origine di ogni componente.
- Il token va in CI come secret, con scope minimo e rotazione: mai nel repository.
Un registry privato risponde a una domanda semplice: come installo un componente che non è pubblico, senza copiarlo a mano? La risposta è un endpoint JSON protetto e un token con permessi limitati.
Il protocollo, in breve
Il CLI chiede un item a un URL, riceve un JSON con file, dipendenze e metadati, poi scrive i file nel progetto. Non c’è magia: se l’endpoint risponde 401 o 403, il CLI si ferma.
{
"registries": {
"@eneui": {
"url": "https://ui.eneawork.it/registry/{name}",
"headers": {
"Authorization": "Bearer ${ENEUI_TOKEN}"
}
}
}
}
Il namespace `@eneui` è ciò che rende leggibile il comando: `npx shadcn@latest add @eneui/hero`. Senza namespace, due registry con lo stesso nome di blocco diventano ambigui.
Dove mettere il token
| Contesto | Dove vive il token | Cosa evitare |
|---|---|---|
| Locale | Variabile d’ambiente della shell | File `.env` committato |
| CI | Secret del provider | Echo del token nei log |
| Produzione | Secret manager | Token nel bundle client |
| Team | Password manager o vault | Token condiviso via chat |
Gli errori che si vedono davvero
| Sintomo | Causa probabile | Verifica |
|---|---|---|
| 401 Unauthorized | Header assente o token scaduto | `curl` con lo stesso header |
| 403 Forbidden | Token valido ma senza accesso all’item | Piano o scope del token |
| 404 Not Found | Nome o namespace sbagliato | URL esatto dell’item |
| 402 Payment Required | Item a pagamento senza accesso | Stato dell’abbonamento |
| File scritti ma import rotti | Dipendenza registry mancante | `dependencies` dell’item |
Su EneUI il codice dei blocchi Pro è protetto lato server: la preview è pubblica, l’item del registry risponde con un errore esplicito finché non c’è accesso. Il client non riceve il codice prima del pagamento, quindi non c’è nulla da aggirare nel browser.
Installazione ripetibile in CI
# .github/workflows/ui.yml
- name: Install UI blocks
run: npx shadcn@latest add @eneui/hero @eneui/pricing --yes
env:
ENEUI_TOKEN: ${{ secrets.ENEUI_TOKEN }}
- Fissa la versione del CLI, non usare `latest` in CI.
- Salva i file generati: l’installazione è deterministica ma la revisione umana no.
- Fai fallire la pipeline sugli errori 401/402/403: sono configurazione, non rumore.
- Rigenera il token con una scadenza e conserva solo l’ultimo.
Namespace e provenienza
Con 1.556 blocchi da 28 registry (31 ottobre 2026) lo stesso nome può esistere in più fonti. Il namespace non è decorazione: è la parte del nome che dice da dove arriva il codice e quale licenza si applica.
La pagina /blocks mostra fonte, licenza, file e dipendenze di ogni blocco prima dell’installazione.
Domande frequenti
Un registry privato richiede un server?
No, serve solo un endpoint che restituisca JSON nel formato registry. Può essere statico se non ci sono dati sensibili.
Il token può stare nel `components.json`?
Meglio di no: il file finisce nel repository. Usa una variabile d’ambiente e lascia il segreto fuori.
Perché serve un namespace?
Per distinguere registry diversi con lo stesso nome di item e per rendere esplicita la provenienza nel comando di install.
Cosa significa 402 Payment Required?
Che l’item esiste ma richiede un accesso a pagamento. È diverso da 403: il token è valido, manca il diritto.
Come ruoto un token senza rompere la CI?
Aggiungi il nuovo token come secret, verifica la pipeline, poi revoca il vecchio. Mai revocare prima del deploy.