Salta al contenuto principale

Routing in Next.js: Come funziona davvero (e perché è geniale)

Profile picture for user luca77king

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

  • /aboutapp/about/page.js

  • /blogapp/blog/page.js

  • /blog/[slug]app/blog/[slug]/page.js

  • /contactapp/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.