
Il routing è il cuore di ogni applicazione web. È ciò che collega un URL a un componente, una pagina o un’azione del server. In Next.js, il routing non è solo una funzionalità: è un paradigma architetturale. Dimentica le configurazioni manuali, le rotte scritte a mano o i file infiniti di setup: Next.js basa tutto sulla struttura delle cartelle. Il filesystem è la mappa dell’applicazione.
Con l’introduzione del nuovo App Router (introdotto con Next.js 13 e ormai standard nelle versioni attuali), il framework ha rivoluzionato il modo in cui si gestiscono le pagine, le rotte dinamiche, il rendering lato server e la navigazione client-side. Oggi, creare un’app complessa in Next.js è questione di organizzazione, non di configurazione.
App Router e struttura base del progetto
Le rotte ora si definiscono nella cartella app/
, non più in pages/
. Ogni sottocartella rappresenta automaticamente una rotta, e ogni file page.js
(o .tsx
) diventa una pagina renderizzata.
Esempio base di struttura:
app/
├─ page.js
├─ about/
│ └─ page.js
├─ blog/
│ ├─ page.js
│ └─ [slug]/
│ └─ page.js
└─ contact/
└─ page.js
Le URL generate saranno:
-
/
→app/page.js
-
/about
→app/about/page.js
-
/blog
→app/blog/page.js
-
/blog/[slug]
→app/blog/[slug]/page.js
-
/contact
→app/contact/page.js
Tutto automatico. Niente file di routing, niente configurazione extra.
Rotte dinamiche e segmenti parametrici
I parametri dinamici sono una delle armi più potenti del sistema di routing di Next.js. Basta usare le parentesi quadre nel nome della cartella per definire un parametro.
Esempio:
app/blog/[slug]/page.js
Questo genera rotte come:
/blog/nextjs-15
/blog/come-creare-un-router
/blog/la-potenza-del-server-rendering
All’interno del file, puoi accedere al parametro in modo semplice:
export default function BlogPost({ params }) {
return <h1>Articolo: {params.slug}</h1>;
}
Puoi anche usare parametri multipli o annidati:
app/products/[category]/[id]/page.js
→ URL come /products/elettronica/123
o /products/abbigliamento/456
.
E per rotte “catch-all”, usa [...slug]
(cattura più segmenti) o [[...slug]]
(segmento opzionale).
Layout e gerarchia di rendering
Una delle differenze fondamentali rispetto al vecchio sistema pages/
è la presenza dei layout annidati. Ogni cartella può avere un file layout.js
che definisce l’interfaccia persistente per quella sezione dell’app (header, sidebar, menu, ecc.).
app/
├─ layout.js
├─ blog/
│ ├─ layout.js
│ ├─ page.js
│ └─ [slug]/page.js
Questo significa che:
-
app/layout.js
gestisce il layout principale (es. header e footer globali) -
app/blog/layout.js
aggiunge elementi specifici per la sezione blog (es. menù laterale, breadcrumb) -
app/blog/[slug]/page.js
si concentra solo sul contenuto del post
Esempio di layout:
export default function BlogLayout({ children }) {
return (
<div className="blog">
<aside>Menu Blog</aside>
<main>{children}</main>
</div>
);
}
I layout sono server components per default, ottimizzati e condivisi tra pagine.
Navigazione client-side con Link e useRouter
La navigazione tra pagine è istantanea grazie al componente Link
di Next.js, che pre-carica le pagine in background per rendere il passaggio fluido.
import Link from "next/link";
export default function Nav() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/blog">Blog</Link>
<Link href="/contact">Contatti</Link>
</nav>
);
}
Per navigare via codice (senza clic), puoi usare l’hook useRouter
:
"use client";
import { useRouter } from "next/navigation";
export default function GoBack() {
const router = useRouter();
return <button onClick={() => router.back()}>Torna indietro</button>;
}
Server Actions e API Routes
Con l’App Router, Next.js unifica il concetto di backend e frontend.
Non c’è più bisogno di pages/api
come in passato: puoi definire server actions direttamente nei componenti server-side.
Esempio:
export default function ContactPage() {
async function sendMessage(formData) {
"use server";
const message = formData.get("message");
await saveMessageToDB(message);
}
return (
<form action={sendMessage}>
<textarea name="message" />
<button type="submit">Invia</button>
</form>
);
}
Questo codice esegue la logica sul server, non nel browser — niente fetch, niente API esterne: Next.js gestisce tutto automaticamente.
Ovviamente, puoi ancora usare la cartella app/api/
per definire endpoint REST:
app/api/posts/route.js
export async function GET() {
const posts = await getAllPosts();
return Response.json(posts);
}
→ disponibile su /api/posts
Rendering: SSG, SSR e ISR
Il routing in Next.js è profondamente connesso al modello di rendering. Ogni pagina può essere generata in modo diverso:
-
Static Generation (SSG): HTML pre-generato in fase di build
-
Server-Side Rendering (SSR): HTML generato a ogni richiesta
-
Incremental Static Regeneration (ISR): statico, ma aggiornabile in background
Nel nuovo App Router, puoi gestire questi comportamenti con le funzioni generateStaticParams
e revalidate
.
Esempio per generare articoli statici aggiornabili ogni 10 secondi:
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map((post) => ({ slug: post.slug }));
}
export const revalidate = 10;
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return <article>{post.content}</article>;
}
Questo unisce il meglio di entrambi i mondi: performance da sito statico e freschezza dei dati server-side.
Rotte parallele e Intercepting Routes
Le versioni più recenti di Next.js introducono concetti avanzati come rotte parallele (@segment
) e intercepting routes, che permettono di visualizzare più sezioni o modali contemporaneamente senza rompere la gerarchia di navigazione.
Ad esempio, puoi aprire un dettaglio di prodotto come modale sopra la pagina principale senza uscire dal contesto corrente — tutto gestito dal router.
Conclusione
Il routing di Next.js 15 non è solo un sistema di navigazione, ma un ecosistema completo per costruire applicazioni React moderne, modulari e performanti.
Con un approccio file-based, il router diventa una mappa logica del progetto, integrando routing, layout, rendering e logica server in un unico flusso coerente.
Che tu stia creando un semplice blog o una piattaforma enterprise, l’App Router di Next.js ti permette di farlo in modo chiaro, scalabile e immediato, riducendo al minimo la configurazione e massimizzando la produttività.
Next.js non ti fa solo scrivere meno codice: ti costringe a scriverlo meglio.