DEV Community

Cover image for Next.js Folder Zen: Padroneggiare la Directory app/
Gavin Cettolo
Gavin Cettolo

Posted on

Next.js Folder Zen: Padroneggiare la Directory app/

Se hai iniziato da poco a usare Next.js 13+, probabilmente hai aperto un progetto e hai pensato:

“Perché questa struttura di cartelle sembra così... diversa?”

Con l’App Router, la directory app/ è diventata il cuore di ogni progetto Next.js moderno. Ma per molti sviluppatori—soprattutto quelli che arrivano dal vecchio pages/ router—la struttura delle cartelle può risultare inizialmente confusa.

Sistemiamo le cose.

TL;DR

  • La directory app/ di Next.js introduce un’architettura basata su file che controlla routing, layout e comportamento del rendering.
  • File speciali come page.tsx, layout.tsx, loading.tsx, error.tsx e not-found.tsx definiscono come si comportano le route.
  • Una struttura pulita con route groups e dynamic routes rende le app Next.js scalabili e manutenibili.

Table of Contents


Perché la directory app/ è importante

Quando Next.js ha introdotto l’App Router, non era solo una nuova cartella.

Era un cambio di paradigma.

Invece di spargere la logica in più livelli, la directory app/ organizza l’app attorno a route e segmenti UI.

Pensala così:

URL → Cartella → UI
Enter fullscreen mode Exit fullscreen mode

Questo approccio rende le applicazioni grandi molto più facili da capire.

Invece di chiederti:

“Dov’è il componente per questa pagina?”

Vai direttamente nella cartella che corrisponde alla route.


Il concetto base: File-Based Routing

Nel app/ directory il routing è semplice.

Le cartelle definiscono le route.

Esempio:

app/
  page.tsx
  about/
    page.tsx
  dashboard/
    page.tsx
Enter fullscreen mode Exit fullscreen mode

Questo genera:

/           → page.tsx
/about      → about/page.tsx
/dashboard  → dashboard/page.tsx
Enter fullscreen mode Exit fullscreen mode

Una pagina base:

export default function Page() {
  return <h1>Hello Next.js</h1>
}
Enter fullscreen mode Exit fullscreen mode

Zero configurazione di routing.


I file essenziali dentro app/

Next.js usa nomi di file speciali per definire il comportamento.

page.tsx

Definisce la UI della route.

export default function Page() {
  return <div>Dashboard</div>
}
Enter fullscreen mode Exit fullscreen mode

Ogni route accessibile deve avere un page.tsx.


layout.tsx

I layout wrappano più pagine e persistono durante la navigazione.

app/
  layout.tsx
  dashboard/
    layout.tsx
    page.tsx
Enter fullscreen mode Exit fullscreen mode

Esempio:

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <main>
      <nav>Navigation</nav>
      {children}
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

I layout non vengono ri-renderizzati durante la navigazione, il che li rende perfetti per:

  • navbar
  • sidebar
  • UI condivisa

Layouts: l’arma segreta

Uno dei punti più forti dell’App Router sono i layout annidati.

app/
  layout.tsx
  dashboard/
    layout.tsx
    analytics/
      page.tsx
Enter fullscreen mode Exit fullscreen mode

Rendering:

Root Layout
   ↓
Dashboard Layout
   ↓
Analytics Page
Enter fullscreen mode Exit fullscreen mode

Questo permette UI complesse senza duplicare codice.


Loading ed Error States

Next.js supporta stati UI a livello di route.

loading.tsx

Mostrato durante il caricamento.

export default function Loading() {
  return <p>Loading...</p>
}
Enter fullscreen mode Exit fullscreen mode

error.tsx

Gestisce errori nel segmento.

"use client" // Gli error boundaries devono essere componenti client

export default function Error({ error }: { error:Error }) {
  return <p>Something went wrong</p>
}
Enter fullscreen mode Exit fullscreen mode

Error Boundaries: una limitazione importante

Il file error.tsx funziona come un gestore di errori React per un segmento di percorso.

Tuttavia, esiste un limite importante che molti sviluppatori trascurano.

I gestori di errori non intercettano gli errori all'interno dei gestori di eventi.

Cattura solo errori durante:

  • rendering
  • server components
  • data fetching

Esempio:

"use client"

export default function Error({
  error,
  reset,
}: {
  error:Error
  reset: () => void
}) {
  return (
    <div>
      <h2>C'è stato un errore.</h2>
      <button onClick={() => reset()}>
        Riprova
      </button>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Gli errori generati all'interno dei gestori di eventi devono comunque essere gestiti manualmente. Ad esempio:

"use client"

export default function Button() {
  const handleClick = () => {
    try {
      throw new Error("Boom");
    } catch (err) {
      console.error(err);
    }
  }
  return <button onClick={handleClick}>Click</button>
}
Enter fullscreen mode Exit fullscreen mode

Considera error.tsx come una rete di sicurezza per l'interfaccia utente, non come un sistema completo di gestione degli errori.


Gestire le 404 con not-found.tsx

Next.js semplifica le 404.

export default function NotFound() {
  return (
    <h2>Pagina non trovata</h2>
  )
}
Enter fullscreen mode Exit fullscreen mode

Trigger:

import {notFound} from "next/navigation"

if (!post) {
  notFound()
}
Enter fullscreen mode Exit fullscreen mode

Supporta livelli multipli:

app/
  not-found.tsx
  dashboard/
    not-found.tsx
Enter fullscreen mode Exit fullscreen mode

Viene usato quello più vicino.


Dynamic Routes

I dynamic routes usano le parentesi quadre.

Ad esempio:

app/
  blog/
    [slug]/
      page.tsx
Enter fullscreen mode Exit fullscreen mode

URL generati:

/blog/my-first-post
/blog/nextjs-routing
/blog/react-performance
Enter fullscreen mode Exit fullscreen mode

Esempio di implementazione:

export default function BlogPost({
  params
}: {
  params: { slug: string }
}) {
  return <h1>{params.slug}</h1>
}
Enter fullscreen mode Exit fullscreen mode

È possibile combinarlo anche con la generazione statica.


Segmenti multipli

Esempio:

app/
  shop/
    [category]/
      [product]/
        page.tsx
Enter fullscreen mode Exit fullscreen mode

Esempi di route generate:

/shop/laptops/macbook-pro
/shop/phones/iphone-15
Enter fullscreen mode Exit fullscreen mode

Esempio di codice:

export default function ProductPage({
  params
}: {
  params: {
    category:string
    product:string
  }
}) {
  return (
    <div>
      <h1>{params.product}</h1>
      <p>Category: {params.category}</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Route Catch-all

A volte servono percorsi flessibili.

Next.js supporta i segmenti catch-all.

[...slug]
Enter fullscreen mode Exit fullscreen mode

Esempio:

app/
  docs/
    [...slug]/
      page.tsx
Enter fullscreen mode Exit fullscreen mode

URL supportati:

/docs
/docs/getting-started
/docs/guides/routing
/docs/api/config
Enter fullscreen mode Exit fullscreen mode

Implementazione:

export default function DocsPage({
  params
}: {
  params: { slug: string[] }
}) {
  return <div>{params.slug?.join("/")}</div>
}
Enter fullscreen mode Exit fullscreen mode

Optional route catch-all

È la versione opzionale:

[[...slug]]
Enter fullscreen mode Exit fullscreen mode

Questo supporta entrambi:

/docs
/docs/routing
/docs/config/api
Enter fullscreen mode Exit fullscreen mode

Tutto gestito dalla stessa pagina.


Comprendere i Route Groups

I Route Groups aiutano a organizzare il codice senza influire sugli URL.

Usano le parentesi tonde:

app/
  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      page.tsx
Enter fullscreen mode Exit fullscreen mode

URL generati:

/
/about
/dashboard
Enter fullscreen mode Exit fullscreen mode

Non appaiono nelle URL e sono perfetti per separare diverse sezioni dell'app così da avere:

  • layout differenti
  • provider differenti
  • strutture UI differenti

Un esempio pratico

app/
  layout.tsx
  page.tsx

  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      layout.tsx
      page.tsx
      analytics/
        page.tsx
      settings/
        page.tsx

  blog/
    page.tsx
    [slug]/
      page.tsx
Enter fullscreen mode Exit fullscreen mode

In questo modo, le pagine di marketing, l'interfaccia utente dell'applicazione e i percorsi dei contenuti rimangono chiaramente separati.


Errori comuni

Quando affianco sviluppatori che utilizzano Next.js, questi sono i problemi che riscontro più frequentemente.

1. Mischiare pages/ e app/

Sebbene tecnicamente possibile, crea confusione.

Se inizi con app/, mantieni solo app.


2. Cartelle annidate

Mantieni la struttura semplice.

Preferisci:

dashboard/analytics
Enter fullscreen mode Exit fullscreen mode

Piuttosto che:

dashboard/features/analytics/pages
Enter fullscreen mode Exit fullscreen mode

3. Ignorare i layout

I layout sono una delle funzionalità più potenti di App Router.

Usateli.

Semplificano notevolmente l'architettura.


Considerazioni finali

La directory app/ potrebbe inizialmente sembrare insolita.

Ma una volta che ci si prende la mano, diventa uno dei modi più puliti per strutturare le applicazioni React.

Invece di dover lottare con la configurazione del routing, i wrapper globali e la duplicazione dei layout, si ottiene un'architettura chiara e prevedibile.

  • Le cartelle rappresentano i percorsi
  • File speciali controllano il comportamento
  • I layout gestiscono l'interfaccia utente condivisa

E improvvisamente il tuo progetto sembra molto più... zen.


Se questo articolo ti è stato utile:

  • lascia un ❤️
  • aggiungi un 🦄
  • raccontami nei commenti come organizzi i tuoi progetti

E se apprezzate contenuti di questo tipo, non esitate a seguirmi qui su DEV per altri post su Next.js, architettura e produttività degli sviluppatori.


EDIT: Questa è una versione riadattata in italiano di questo mio precedente articolo: Next.js Folder Zen: Mastering the app/ Directory

Top comments (0)