React
Struttura di un progetto Next.js App Router nel 2026
Dove mettere pagine, componenti, blocchi e utility in un progetto App Router. Una struttura che regge quando il progetto cresce, senza cartelle ceremoniali.
In sintesi
- L’App Router organizza URL e confini server/client, non il design system.
- Tieni `components/ui` per le primitive e `components/blocks` per le sezioni composte.
- Ogni cartella in più deve ridurre un rischio: se non lo fa, è cerimonia.
La struttura di un progetto non si giudica dalla profondità delle cartelle. Si giudica da una domanda: dove guardo per capire se un file può essere usato dal server o dal client? L’App Router risponde con i confini, non con le mode.
Una struttura che regge
app/
(marketing)/
page.tsx
pricing/page.tsx
(app)/
dashboard/
layout.tsx
page.tsx
layout.tsx
components/
ui/ # primitive: button, input, dialog
blocks/ # sezioni: hero, pricing, navbar
app/ # composizioni legate al prodotto
lib/
utils.ts
tokens.css
hooks/
public/
`(marketing)` e `(app)` sono route group: non aggiungono segmenti all’URL, ma separano layout e confini. Servono quando le due parti hanno esigenze diverse di navigazione e caching.
Responsabilità delle cartelle
| Cartella | Contenuto | Regola |
|---|---|---|
| app/ | Route, layout, loading, error | Solo ciò che è URL o confine |
| components/ui/ | Primitive senza logica di prodotto | Nessuna chiamata dati |
| components/blocks/ | Sezioni composte | Props esplicite, nessun fetch globale |
| components/app/ | UI legata a una feature | Può conoscere il dominio |
| lib/ | Utility e configurazione | Funzioni pure quando possibile |
Server e client: il confine che conta
Un componente è server per default. `"use client"` va messo il più in basso possibile, sul componente che ha davvero stato o eventi. Metterlo sul layout trasforma l’intero albero in client e perdi il vantaggio del framework.
- Il layout può restare server: passa dati ai client component come props.
- Un dialog interattivo è client; la pagina che lo ospita può essere server.
- Le fetch vanno nel server component o in una route dedicata, non dentro `components/ui`.
Dove entrano i componenti del catalogo
Installa le primitive in `components/ui` e i blocchi in `components/blocks`. Non mescolare le due cose: la primitiva ha una API stabile, il blocco è una composizione che adatti al contesto.
Il catalogo EneUI indicizza 111.985 componenti da 1.472 librerie e 1.556 blocchi (31 ottobre 2026). Installare un blocco non significa adottare una libreria: il codice entra nel tuo repository e segue la tua struttura.
Gli errori che costano di più
- Una cartella per ogni tipo di file (`containers`, `views`, `screens`) senza una regola che le distingua.
- `"use client"` sul layout radice.
- Fetch duplicate tra layout e pagina.
- Componenti UI che importano store o contesti di prodotto.
Domande frequenti
Meglio `src/` o la root?
È indifferente per Next.js. Scegli una convenzione e non duplicarla: due alberi di codice sono il vero costo.
Dove metto i componenti shadcn?
In `components/ui`. Sono primitive, non sezioni: separarle dai blocchi evita import incrociati.
Le route group sono obbligatorie?
No. Servono quando due aree del sito hanno layout o esigenze di caching diverse. Se non è il caso, non aggiungerle.
Posso fare fetch in un client component?
Puoi, ma perdi il rendering server e aggiungi stati di caricamento. Preferisci il server component e passa i dati come props.
Come organizzo i test?
Accanto al componente per unit test, in una cartella `tests/` per i flussi end-to-end. La posizione conta meno della distinzione.