Next.js
Promemoria Next.js 16: 75 pattern dell'App Router per la produzione
Un promemoria pratico di Next.js 16 con 75 comandi, convenzioni dei file, pattern di Server Components, API di cache, campi SEO, verifiche di sicurezza e consigli sulla distribuzione.
Usa questo riferimento durante lo sviluppo di progetti App Router con Next.js 16. Ogni voce risponde a una domanda precisa, con codice copiabile quando conta la sintassi.
Configurazione e comandi del progetto
Avvia, esamina e aggiorna un progetto Next.js 16 con comandi riproducibili. Gli esempi usano npm, ma i concetti del framework sono indipendenti dal gestore dei pacchetti.
- 1
Crea un nuovo progetto App Router
create-next-app configura Next.js, React, TypeScript e gli strumenti scelti. Salva package-lock.json nei commit del progetto.
npx create-next-app@latest my-app --ts --app --src-dir - 2
Usa la versione minima attuale di Node.js
Next.js 16 richiede Node.js 20.9 o successivo. Fissa una versione supportata nello sviluppo locale e nella CI, così le compilazioni non dipendono dalle impostazioni predefinite mutevoli del runner.
- 3
Conosci i quattro script standard
next dev avvia lo sviluppo, next build crea l'output di produzione, next start serve quell'output e il linter configurato viene eseguito separatamente.
"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint ." } - 4
Installa in modo riproducibile nella CI
Usa npm ci quando package-lock.json è salvato nei commit. Rifiuta le divergenze del lockfile e installa l'albero delle dipendenze risolto senza riscriverlo.
npm ci && npm run build - 5
Usa Turbopack per impostazione predefinita
In Next.js 16, next dev e next build usano entrambi Turbopack per impostazione predefinita. Rimuovi i vecchi flag --turbo, salvo che uno script debba supportare un'altra versione.
- 6
Mantieni temporaneamente una compilazione webpack
Un progetto con configurazione webpack personalizzata può scegliere esplicitamente un builder alternativo mentre la configurazione viene migrata. Verifica output e prestazioni prima di cambiare il builder di produzione.
next build --webpack - 7
Mantieni il codice applicativo sotto src
src/app e src/lib separano il codice applicativo dalla configurazione radice. La directory public e file come next.config.ts rimangono nella radice del progetto.
- 8
Usa un alias di importazione
Un alias stabile evita lunghi percorsi relativi quando il codice si sposta tra cartelle delle route. Mantieni l'alias in tsconfig.json o jsconfig.json.
import { getUser } from "@/lib/data";
Pagine, layout e instradamento
L'App Router è un router basato sul file system. Queste convenzioni controllano URL, interfaccia condivisa, parametri dinamici e comportamento avanzato della navigazione.
- 9
Crea una pagina
Un file page.tsx rende pubblicamente accessibile la route della propria cartella. L'esportazione predefinita definisce l'interfaccia di quell'URL.
export default function Page() { return <h1>About</h1>; } - 10
Crea il layout radice obbligatorio
app/layout.tsx avvolge ogni route e deve renderizzare html e body. Inserisci qui CSS globale, lingua, provider comuni a tutto il sito e metadati predefiniti.
- 11
Annida i layout per segmento di route
Un layout dentro app/dashboard avvolge la pagina della dashboard e tutti i discendenti. I layout persistono durante la navigazione nel client all'interno del proprio sottoalbero.
- 12
Raggruppa le route senza cambiare l'URL
Le parentesi creano un gruppo di route. app/(marketing)/pricing/page.tsx continua a risolversi in /pricing.
app/(marketing)/pricing/page.tsx - 13
Crea un segmento dinamico
Le parentesi quadre acquisiscono un segmento URL. In Next.js 16, attendi params prima di leggere il valore.
export default async function Page({ params }) { const { slug } = await params; return <h1>{slug}</h1>; } - 14
Cattura diversi segmenti
[...parts] è un catch-all obbligatorio e [[...parts]] è facoltativo. Usali per documentazione gerarchica o altri percorsi la cui profondità dipende dai dati.
- 15
Pregenera i percorsi dinamici noti
generateStaticParams restituisce oggetti di parametri per le route che Next.js deve generare durante la compilazione.
export function generateStaticParams() { return posts.map((post) => ({ slug: post.slug })); } - 16
Rifiuta i percorsi dinamici sconosciuti
Imposta dynamicParams su false quando devono essere risolti solo i valori restituiti da generateStaticParams. Gli altri valori dei parametri restituiscono 404.
export const dynamicParams = false; - 17
Mostra lo stato di risorsa mancante
Chiama notFound quando la route esiste ma l'entità richiesta no. Next.js renderizza il confine not-found.tsx più vicino.
if (!post) notFound(); - 18
Ripristina lo stato con un template
template.tsx assomiglia a un layout, ma viene rimontato durante la navigazione. Usalo quando stato ed effetti devono essere ripristinati; conserva le strutture persistenti nei layout.
- 19
Renderizza slot di route simultanei
Cartelle come @team e @analytics definiscono slot di route parallele passati a un layout genitore. Fornisci fallback default.tsx per gli slot senza corrispondenza durante una navigazione completa.
- 20
Apri una route come finestra modale
Le route intercettanti possono mostrare un'altra route nel layout corrente durante la navigazione nel client, conservando il risultato a pagina intera per ricaricamenti e link condivisi.
Server Components e Client Components
I Server Components sono l'impostazione predefinita dell'App Router. Aggiungi JavaScript nel browser solo ai componenti che richiedono interazione o API esclusive del browser.
- 21
Mantieni le pagine sul server per impostazione predefinita
Un Server Component può attendere i dati, usare variabili di ambiente private e renderizzare senza inviare il proprio codice al browser.
- 22
Dichiara un Client Component
Inserisci la direttiva prima delle importazioni. Il confine del client comprende quel modulo e il grafo di dipendenze lato client che importa.
"use client"; import { useState } from "react"; - 23
Usa il client per l'interazione
Stato, effetti, gestori di eventi, hook personalizzati, window, localStorage e altre API del browser appartengono ai Client Components.
- 24
Usa il server per il lavoro privato
Query al database, credenziali dei servizi, grandi librerie esclusive del server e la maggior parte del rendering dei contenuti appartengono ai Server Components o a moduli server-only.
- 25
Passa props serializzabili ai client
Stringhe, numeri, booleani, array, oggetti semplici e valori React supportati possono attraversare il confine. Limita i dati e non passare record privati completi.
- 26
Contrassegna i moduli privati con server-only
L'importazione per effetto collaterale fa fallire un'importazione nel client durante la compilazione e protegge il codice di accesso ai dati dall'uso accidentale nel browser.
import "server-only"; - 27
Sposta il confine del client più in basso
Mantieni pagina e layout renderizzati sul server, poi isola casella di ricerca, menu, selettore o grafico nel Client Component più piccolo possibile.
- 28
Passa l'interfaccia del server tramite i figli del client
Un Client Component può ricevere un Server Component come figlio o come altra prop. Così il sottoalbero renderizzato sul server rimane fuori dal grafo dei moduli del client.
- 29
Inserisci i provider il più in profondità possibile
Context non è disponibile nei Server Components. Renderizza un provider mirato in un Client Component attorno al solo sottoalbero che lo usa, senza racchiudere per impostazione predefinita l'intero documento.
Recupero dati, streaming e cache
Scegli consapevolmente quanto devono essere aggiornati i dati. In Next.js 16, Cache Components richiede un'attivazione esplicita; il promemoria indica le API che necessitano di quella configurazione.
- 30
Recupera dati in un Server Component asincrono
Chiama un'API, un ORM o un database dal componente che renderizza il risultato. Non serve un Route Handler interno soltanto per chiamare il tuo stesso server.
export default async function Page() { const products = await getProducts(); return <ProductList products={products} />; } - 31
Avvia insieme le attività indipendenti
Promise.all evita una sequenza inutile di richieste quando nessuna operazione richiede il risultato dell'altra.
const [user, projects] = await Promise.all([ getUser(), getProjects(), ]); - 32
Usa lo streaming con un file di caricamento della route
loading.tsx racchiude il segmento in un confine Suspense e fornisce subito un'interfaccia di fallback durante navigazione e rendering al momento della richiesta.
- 33
Invia in streaming una sezione lenta
Racchiudi il componente lento in Suspense, così il resto della pagina può essere renderizzato prima. Fai corrispondere il fallback alle dimensioni finali.
<Suspense fallback={<ActivitySkeleton />}> <RecentActivity /> </Suspense> - 34
Usa la memoizzazione per un singolo rendering
React cache può deduplicare chiamate alla stessa funzione dati sul server con gli stessi argomenti durante un rendering. Non è una cache persistente dei dati applicativi.
import { cache } from "react"; export const getUser = cache(async (id) => db.user.findUnique({ where: { id } })); - 35
Abilita Cache Components
Le API use cache di Next.js 16 richiedono l'impostazione cacheComponents. Migra consapevolmente, perché questo cambia il comportamento di rendering e cache.
const nextConfig = { cacheComponents: true }; export default nextConfig; - 36
Memorizza in cache una funzione asincrona
Con Cache Components abilitato, inserisci use cache all'inizio del corpo di una funzione asincrona o di un componente. Gli argomenti serializzabili diventano parte della chiave di cache.
export async function getProducts() { "use cache"; return db.product.findMany(); } - 37
Imposta la durata della cache
cacheLife accetta un profilo con nome o valori temporali personalizzati. Scegli la durata in base a quanto il contenuto può restare obsoleto, non alla comodità.
"use cache"; cacheLife("hours"); - 38
Assegna tag al lavoro correlato in cache
cacheTag assegna a più voci un'etichetta comune di invalidazione, come products o post-42.
"use cache"; cacheTag("products"); - 39
Fai scadere la cache di un percorso
Chiama revalidatePath da una Server Function o da un Route Handler dopo una modifica che rende obsoleta una pagina o un layout.
revalidatePath("/blog"); - 40
Rivalida per tag
Usa revalidateTag quando i contenuti con tag possono adottare il comportamento stale-while-revalidate. Scegli il profilo di cache adatto al requisito di aggiornamento dei dati.
- 41
Leggi subito la tua modifica con updateTag
Chiama updateTag dentro una Server Action quando l'utente dell'azione deve vedere subito i dati aggiornati associati ai tag dopo la modifica.
await savePost(input); updateTag("posts");
Moduli, modifiche e Route Handlers
Le scritture richiedono validazione, autorizzazione, errori prevedibili e aggiornamento esplicito della cache. Le interfacce HTTP richiedono anche la normale sicurezza degli endpoint.
- 42
Dichiara una Server Action
Inserisci use server all'inizio di una funzione asincrona o di un modulo di azioni. Le Server Actions esportate devono essere trattate come endpoint di modifica chiamabili da remoto.
"use server"; export async function createPost(formData: FormData) { // validate, authorize, mutate, invalidate } - 43
Collega un'azione a un modulo
Un modulo può chiamare una Server Action senza un gestore di invio personalizzato nel client. Il comportamento nativo dei moduli nel browser offre anche un percorso di miglioramento progressivo.
<form action={createPost}>...</form> - 44
Convalida FormData sul server
Tratta nomi, ID, file, campi nascosti e validazione lato client come non attendibili. Valida rispetto a uno schema esplicito prima di scrivere.
- 45
Restituisci gli errori previsti del modulo
Usa un risultato serializzabile e useActionState per errori di validazione o business correggibili dall'utente. Non lanciare eccezioni per ogni esito previsto.
- 46
Mostra lo stato di invio in attesa del modulo
useFormStatus legge lo stato dell'invio del modulo genitore. Disabilita invii ripetuti e assegna al pulsante un'etichetta che indichi correttamente l'attesa.
- 47
Crea un Route Handler
route.ts esporta funzioni per i verbi HTTP e usa le API Web Request e Response. Un file route.ts non può condividere lo stesso segmento con page.tsx.
export async function GET() { return Response.json({ status: "ok" }); } - 48
Leggi un parametro dinamico di un Route Handler
Nella versione attuale di Next.js, params del contesto della route è asincrono. Attendilo prima di interrogare la risorsa.
export async function GET(request, { params }) { const { id } = await params; return Response.json(await getItem(id)); } - 49
Reindirizza dopo una modifica
Usa redirect per una navigazione temporanea dopo una creazione o un aggiornamento riuscito e permanentRedirect solo quando la risorsa ha un nuovo URL canonico permanente.
redirect("/dashboard"); - 50
Rendi sicuri i nuovi tentativi
Webhook e richieste di rete possono arrivare più volte. Salva ID degli eventi dei provider o chiavi di idempotenza prima di ripetere pagamenti, email o altri effetti collaterali.
SEO, immagini, font e script
Next.js può generare tag head e file dei crawler dal codice delle route. La pagina visibile richiede comunque contenuti specifici e utili e una struttura semantica.
- 58
Imposta metadati statici
Esporta i metadati da un layout o da una pagina Server Component quando i valori non dipendono dai dati della route.
export const metadata = { title: "Pricing", description: "Simple plans for growing teams.", }; - 59
Genera metadati dinamici
Usa generateMetadata per titoli, descrizioni, URL canonici e immagini di condivisione specifici dell'entità. Riusa la funzione di accesso ai dati della route dove possibile.
- 60
Imposta metadataBase una sola volta
metadataBase nel layout radice permette a link canonici e campi delle immagini di usare percorsi relativi, mentre Next.js risolve gli URL assoluti.
metadataBase: new URL("https://example.com") - 61
Genera una sitemap
app/sitemap.ts restituisce URL pubblici e campi facoltativi lastModified, changeFrequency e priority. Generala dal catalogo reale dei contenuti; Google ignora changeFrequency e priority, quindi mantieni accurato lastModified senza simulare aggiornamenti.
- 62
Pubblica le regole robots
app/robots.ts restituisce regole di scansione e posizione della sitemap. Le regole robots sono indicazioni per i crawler, non controlli di accesso alle route private.
- 63
Usa immagini ottimizzate
next/image richiede dimensioni intrinseche o un contenitore fill. Fornisci testo alt accurato e sizes adatto alle diverse dimensioni dello schermo; usa priority solo per immagini davvero critiche visibili senza scorrere.
- 64
Carica i font con next/font
next/font ospita direttamente i file dei font scelti e riduce le richieste esterne. Limita pesi e sottoinsiemi agli stili effettivamente usati dall'interfaccia.
- 65
Pianifica script di terze parti
next/script controlla quando viene caricato JavaScript esterno. Scegli afterInteractive o lazyOnload, salvo che l'integrazione appartenga davvero al percorso critico.
Sicurezza e configurazione
I confini del framework riducono l'esposizione accidentale solo quando il codice applicativo mantiene esplicite autorizzazione e gestione dei segreti.
- 66
Mantieni i segreti sul server
I valori di ambiente sono esclusivi del server, salvo che il nome inizi con NEXT_PUBLIC_. Considera ogni valore con quel prefisso visibile nel browser e fissato secondo l'ambiente di compilazione.
- 67
Verifica l'autorizzazione in ogni punto d'ingresso del server
Verifica identità corrente e permessi nelle Server Actions, nei Route Handlers e nell'accesso ai dati protetti. Un pulsante nascosto o un reindirizzamento Proxy non costituiscono un confine di sicurezza.
- 68
Usa Proxy per la logica di instradamento legata alla richiesta
Next.js 16 usa proxy.ts per riscritture, reindirizzamenti e controlli preliminari prima che una richiesta raggiunga una route. Mantieni anche l'autorizzazione sicura vicino ai dati.
- 69
Usa cookie di sessione sicuri
Imposta gli attributi HTTP-only, secure, same-site, path e scadenza in base al modello della sessione. Ruota e invalida le sessioni tramite il sistema di autenticazione.
- 70
Invia al browser solo i dati necessari
Converti i record in DTO che contengano solo i campi necessari all'interfaccia. Le API taint possono aggiungere difesa in profondità, ma non sostituiscono un'attenta definizione dell'output.
Produzione, debug e distribuzione
Le ultime cinque verifiche trasformano il codice del framework in un sito gestibile, con compilazioni riproducibili e rilasci osservabili.
- 71
Esegui i controlli separatamente
Next.js 16 non usa next build per eseguire il lint. Separa lint, TypeScript, test e compilazione di produzione in passaggi distinti della CI.
npm run lint npx tsc --noEmit npm test npm run build - 72
Verifica il server di produzione
Esegui next build e next start in locale o in un'anteprima. Il comportamento in sviluppo può nascondere problemi di importazioni, cache, ambiente e rendering presenti solo in produzione.
- 73
Leggi il riepilogo delle route nella compilazione
L'output di next build identifica le route prerenderizzate e quelle renderizzate al momento della richiesta. Indaga una route che diventa dinamica o cresce inaspettatamente, senza ridurre la compilazione a un semplice esito positivo o negativo.
- 74
Esponi una route di verifica dello stato veritiera
Restituisci una piccola risposta di successo solo quando il processo è pronto a ricevere traffico. Tieni segreti e informazioni dettagliate sulle dipendenze fuori dal corpo pubblico.
export function GET() { return Response.json({ status: "ok" }); } - 75
Distribuisci il normale processo di produzione
Una distribuzione server standard installa dal lockfile, esegue next build, avvia con next start, fornisce i segreti dell'ambiente di esecuzione, verifica lo stato e promuove solo un rilascio sano.
build_cmd: npm ci && npm run build start_cmd: npm start runtime: name: node@24 port: 3000 health_path: /api/health