Adios
BlogNext.js

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.

Team di AdiosAggiornato 17 luglio 202622 min di lettura

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. 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. 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. 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. 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. 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. 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. 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. 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.

  1. 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>;
    }
  2. 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.

  3. 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.

  4. 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
  5. 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>;
    }
  6. 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.

  7. 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 }));
    }
  8. 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;
  9. 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();
  10. 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.

  11. 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.

  12. 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.

  1. 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.

  2. 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";
  3. 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.

  4. 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.

  5. 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.

  6. 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";
  7. 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.

  8. 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.

  9. 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.

  1. 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} />;
    }
  2. 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(),
    ]);
  3. 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.

  4. 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>
  5. 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 } }));
  6. 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;
  7. 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();
    }
  8. 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");
  9. 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");
  10. 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");
  11. 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.

  12. 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.

  1. 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
    }
  2. 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>
  3. 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.

  4. 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.

  5. 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.

  6. 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" });
    }
  7. 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));
    }
  8. 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");
  9. 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.

  1. 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.",
    };
  2. 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.

  3. 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")
  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  1. 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
  2. 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.

  3. 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.

  4. 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" });
    }
  5. 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
Tutti gli articoli