8 ottobre 2026
TanStack Router in React: route type-safe, loader robusti e rotte protette senza “colla” nel codice
Dalla route tree generata automaticamente ai search params tipizzati: un approccio moderno per app complesse, con meno stato locale e più coerenza.
TanStack Router sta diventando una scelta sempre più naturale per applicazioni React articolate: routing dichiarativo, type-safety reale, loader per gestire i dati a livello di rotta, search params tipizzati e protezione delle pagine private. In questo articolo vediamo come ragionare con la route tree, perché il file-based routing cambia il modo di progettare la navigazione e quali vantaggi pratici porta in produzione rispetto a soluzioni più “string-based”.
TanStack Router è uno di quei tool che, una volta capiti i meccanismi, cambiano il modo in cui strutturi un’app React: meno “colla” nei componenti (stato e side-effect sparsi), più logica spostata dove ha senso—nel routing. Il risultato è un’architettura più leggibile, più verificabile e, soprattutto, più type-safe.
In questo articolo mettiamo a fuoco i concetti che fanno davvero la differenza: route tree, root route, file-based routing, loader, search params tipizzati e rotte protette.
Perché serve un router (davvero)
Un router non è solo “cambio pagina senza reload”. È il meccanismo che traduce l’intento dell’utente (un URL) nell’interfaccia corretta.
- L’utente visita
/items/phones→ vuole vedere i telefoni. - Cambia a
/items/cats→ vuole vedere i gatti.
Questa corrispondenza URL → UI porta due benefici fondamentali:
- Deep linking: ogni punto dell’app può essere raggiunto con un URL condivisibile e bookmarkabile.
- Separazione delle responsabilità: la navigazione e la selezione della “pagina” non dipendono da
useEffecte variabili locali, ma da regole dichiarative.
Pensalo come un GPS: prende l’URL, lo interpreta, decide dove “portare” l’utente e quale componente renderizzare.
Cosa rende TanStack Router diverso
Molte librerie risolvono il problema del routing (React Router DOM, i router integrati dei framework, ecc.). TanStack Router punta a un obiettivo molto specifico: rendere il routing un’API altamente tipizzata e scalabile.
1) Type-safety “seria” (non cosmetica)
Uno dei problemi più comuni dei router “string-based” è banale ma costoso: scrivi un percorso a mano, sbagli una lettera, e scopri l’errore solo in produzione con un 404.
Con TanStack Router l’idea è opposta: se il progetto è configurato correttamente, molti errori diventano impossibili o vengono segnalati dal type checker/IDE quando stai scrivendo codice.
2) File-based routing
Le rotte derivano da file e cartelle: la struttura del filesystem diventa una rappresentazione concreta dell’albero di navigazione. Questo riduce configurazioni verbosissime e ti obbliga (in senso buono) a mantenere una gerarchia chiara.
3) Loader e dati “router-driven”
La parte più interessante per app complesse: caricare i dati a livello di route invece che dentro i componenti con useEffect.
- la rotta decide cosa serve
- il componente si concentra su come mostrarlo
Questo approccio tende a ridurre stato derivato, condizioni sparse, loading duplicati e fetch ripetuti.
Setup: partire col piede giusto
TanStack mette a disposizione una CLI per generare lo scaffolding del progetto router-first.
Concettualmente, il flusso è:
- crei un progetto con lo scaffolding del router
- selezioni framework (React)
- avvii in dev e inizi a costruire le rotte tramite file
Nel progetto troverai anche configurazioni già pronte per plugin utili (es. devtools) e impostazioni pensate per migliorare l’esperienza di sviluppo.
La route tree: il cuore dell’architettura
Quando lavori con file-based routing, l’app non ragiona “direttamente” sui file: serve una struttura intermedia che rappresenti l’albero delle rotte.
Per questo entra in gioco un file generato automaticamente (tipicamente qualcosa come routeTree.gen.ts).
Punti chiave:
- viene generato: non si modifica a mano
- contiene la gerarchia completa delle rotte
- abilita type inference e collegamenti affidabili tra path, parametri e navigazione
Root route e convenzioni
Di solito c’è un file speciale per la root route (es. _root.tsx).
Poi, a livello di cartella routes, le convenzioni più comuni sono:
index.tsx→ la rotta/(home)about.tsx→ la rotta/aboutlogin.tsx→ la rotta/login
Da lì in poi, cartelle annidate = rotte annidate.
Questo modello diventa potentissimo quando inizi ad avere:
- layout diversi per sezioni dell’app
- pagine statiche e aree dinamiche
- contenuti con URL significativi (SEO e condivisione)
Rotte dinamiche: URL data-driven
In applicazioni reali, spesso una parte dell’URL non è fissa: dipende dai dati.
Esempio classico: una pagina “dettaglio meetup”:
/activity/meetup/tapascript/activity/meetup/react-milano
Quella “coda” (tapascript, react-milano, …) non dovrebbe essere hardcoded nei componenti. L’ideale è che:
- la route dichiari il parametro dinamico
- un loader usi quel parametro per recuperare i dati
- il componente renderizzi i dettagli
Quando questo è ben tipizzato, ottieni un vantaggio enorme: i parametri non sono più stringhe indefinite, ma valori previsti dal routing.
Loader: dati prima del rendering, con responsabilità chiare
L’idea dei loader è semplice e molto efficace:
- la rotta definisce come recuperare i dati necessari
- la UI riceve dati pronti (e gestisce gli stati di loading/error in modo coerente)
Questo tende a eliminare molti pattern comuni ma fragili:
useEffectche dipendono da parametri di URL- “loading state” duplicati in più componenti
- fetch ripetuti perché un componente rimonta
In un’app strutturata bene, il routing diventa il punto naturale dove orchestrare:
- prefetch
- caching
- invalidazioni e refresh
Search params tipizzati: filtri e stato URL-friendly
Una delle tentazioni più frequenti è usare stato locale per i filtri (checkbox, dropdown, query di ricerca). Funziona, ma spesso perdi:
- condivisione dell’URL con i filtri attivi
- ripristino dello stato al refresh
- navigazione browser (back/forward) coerente
Gestire filtri e ricerca attraverso i search params (query string) è spesso la scelta migliore, e TanStack Router spinge verso una gestione più rigorosa e tipizzata.
Risultato pratico:
- filtri riproducibili e condivisibili
- meno stato “volatile” nei componenti
- meno ambiguità su cosa rappresenti lo stato dell’app
Router context vs React context: quando usarli
TanStack Router supporta un concetto di router context per passare informazioni lungo il routing.
È utile quando i dati sono naturalmente legati alla navigazione (ad esempio informazioni di sessione, feature flag legati a sezioni, dipendenze del layer di routing).
Detto questo, non è un rimpiazzo automatico del React context: se stai modellando stato UI generico o logica non legata alle rotte, spesso il contesto React tradizionale resta più appropriato.
La regola pratica: usa router context per ciò che “appartiene” alla navigazione; React context per ciò che appartiene alla UI o al dominio in senso più ampio.
Rotte protette: private area senza hack
Quasi ogni prodotto reale ha aree riservate:
- dashboard
- creazione/modifica di contenuti
- impostazioni utente o admin
Il punto non è solo “bloccare la pagina”, ma farlo in modo coerente e prevedibile:
- se non sei autenticato e tenti di accedere a una rotta privata → redirect a
/login - dopo login → ritorno al flusso (o accesso alla rotta richiesta)
- messaggi e regole non sparsi nei componenti, ma definiti nel routing
Quando la protezione è router-driven, diventa più difficile dimenticarsi un controllo in una pagina secondaria.
Un modello mentale utile: dall’app “component-driven” all’app “route-driven”
Molti progetti React partono così:
- componenti che leggono parametri
useEffectche fetchano dati- stato locale che replica l’URL
TanStack Router ti invita a ribaltare l’approccio:
- la rotta conosce parametri e dipendenze
- il loader conosce il fetching
- il componente conosce il rendering
Quando questa separazione regge, l’app è più facile da estendere: aggiungere una nuova sezione o un nuovo layout è spesso una questione di struttura delle rotte, non di incollare logica in giro.
Sintesi e implicazione pratica
TanStack Router non è “solo un altro router”: è un modo più rigoroso di progettare la navigazione in React, particolarmente adatto quando l’app cresce e inizi ad avere bisogno di:
- rotte annidate con layout coerenti
- parametri dinamici e pagine data-driven
- loader affidabili e riutilizzabili
- filtri via URL (search params) tipizzati
- protezione delle aree private definita a livello di routing
Se oggi ti capita di vedere useEffect ovunque per inseguire l’URL, o stringhe di path scritte a mano in dieci punti diversi del codice, il passaggio a un routing type-safe e route-driven è uno di quei cambiamenti che ripagano rapidamente—in stabilità, debug e manutenzione.