Quando si sviluppa un sito multilingue con Next.js, uno dei problemi più comuni che si presentano riguarda la gestione della lingua di default. Se hai mai lavorato su un progetto e-commerce o un sito aziendale multilingue, ti sarai sicuramente imbattuto in questa sfida: come gestire correttamente il redirect dalla root (/
) verso la lingua di default senza creare problemi di SEO o di user experience?
Next.js offre un ottimo supporto per l'internazionalizzazione attraverso il sistema i18n integrato, ma presenta alcune limitazioni quando si tratta di gestire la root del sito. In questo articolo, ti mostrerò come ho implementato una soluzione basata su un brillante workaround di Daniel Gördes (disponibile su GitHub), che ho adattato dal formato TypeScript a JavaScript e personalizzato per le specifiche esigenze dei progetti su cui lavoro.
Il problema dell'i18n in Next.js
Il framework Next.js gestisce l'internazionalizzazione in modo automatico aggiungendo prefissi di lingua agli URL. Per esempio, un sito con supporto per italiano, inglese e francese avrà URL come:
/it/about
per la versione italiana/en/about
per la versione inglese/fr/about
per la versione francese
Il problema sorge quando si vuole gestire la lingua di default. Molti siti web preferiscono non mostrare il prefisso della lingua per la versione principale (spesso quella in lingua locale del paese dove opera l'azienda). Vorrebbero quindi:
/about
per la lingua di default (invece di/it/about
)/en/about
per l'inglese/fr/about
per il francese
Next.js con i18n abilitato non passa la root /
attraverso redirects()
nel next.config.js
, rendendo impossibile gestire questo scenario con le configurazioni standard. Inoltre, si presentano differenze di comportamento tra l'ambiente di sviluppo locale e la piattaforma di hosting Vercel.
Prefisso lingua: usarlo o non usarlo?
Prima di addentrarci nella soluzione tecnica, è importante considerare quando e perché potresti voler evitare il prefisso di lingua per la versione di default. La scelta non è sempre ovvia e dipende da diversi fattori.
Vantaggi di mantenere i prefissi per tutte le lingue
Utilizzare il prefisso anche per la lingua di default (/it/about
, /en/about
, /fr/about
) presenta alcuni vantaggi significativi:
- Migrazione da siti esistenti: può accadere che occorra mantenere gli stessi URL del precedente sito per preservare il ranking SEO e non rompere i link esistenti
- Coerenza: tutti gli URL seguono la stessa struttura, rendendo il sistema più prevedibile
- Scalabilità: aggiungere nuove lingue non richiede modifiche alla struttura URL esistente
- Chiarezza per gli utenti: è sempre evidente in quale lingua si trova la pagina
- Analytics più pulite: è più facile tracciare le performance per lingua senza logiche aggiuntive
Perché scegliere di rimuovere il prefisso
Tuttavia, ci sono scenari validi in cui preferire URL senza prefisso per la lingua principale:
- Brand perception: alcuni brand preferiscono URL più "puliti" per il mercato principale
- User experience: URL più corti possono essere percepiti come più user-friendly
- Marketing: campagne pubblicitarie con URL più semplici da comunicare
La decisione strategica
La scelta dovrebbe basarsi su:
- Obiettivi SEO: hai URL esistenti da preservare?
- Target audience: il tuo pubblico principale si aspetta URL in una lingua specifica?
- Scalabilità futura: prevedi di aggiungere molte altre lingue?
- Risorse di sviluppo: hai il tempo per implementare e mantenere una soluzione personalizzata?
Nel caso in cui la tua analisi porti verso l'aggiunta del prefisso per la lingua di default, la soluzione che segue ti permetterà di implementarla in modo pulito e performante.
La soluzione: middleware personalizzato
Per risolvere questo problema, ho adattato una soluzione proposta da Daniel Gördes su GitHub che utilizza un middleware Next.js che ho combinato con una configurazione i18n speciale. Il workaround originale, sviluppato in TypeScript, l'ho convertito in JavaScript e personalizzato per le esigenze specifiche dei miei progetti.
L'idea brillante alla base di questa soluzione è creare una lingua virtuale chiamata 'default'
che cattura le visite alla root (https://localhost:3000
) e le reindirizza automaticamente alla lingua effettiva desiderata.
Configurazione di next-i18next
Per prima cosa, creiamo il file di configurazione next-i18next.config.js
:
/*
* next-i18next.config.js
*
* Configurazione per la gestione dell'i18n con lingua di default senza prefisso
*/
module.exports = {
i18n: {
locales: ['default', 'it', 'en', 'fr'], // Lingue supportate + lingua virtuale
defaultLocale: 'default', // Lingua di default virtuale
localeDetection: false // Disabilita il rilevamento automatico
}
};
La chiave di questa configurazione è l'aggiunta di 'default'
come prima lingua nell'array locales
. Questa non è una lingua reale, ma un placeholder che ci permette di intercettare le visite alla root del sito.
Implementazione del middleware
Il cuore della soluzione è il middleware che si occupa di gestire i redirect:
/*
* middleware.js
*
* Gestisce il redirect automatico dalla root verso la lingua di default
*/
import { NextResponse } from 'next/server';
// Regex per identificare file statici
const PUBLIC_FILE = /\.([a-zA-Z0-9]+$)/;
export function middleware(request) {
// Workaround per Vercel: pulizia del pathname
const cleanPathName = request.nextUrl.pathname.startsWith('/default')
? request.nextUrl.pathname.replace('/default', '/').replace('//', '/')
: request.nextUrl.pathname;
// Condizioni per applicare la logica di redirect
const shouldHandleLocale =
!PUBLIC_FILE.test(cleanPathName) && // Esclude file statici
!cleanPathName.includes('/api/') && // Esclude API routes
request.nextUrl.locale === 'default'; // Solo se locale è 'default'
// Redirect condizionale alla lingua italiana (o quella desiderata)
return shouldHandleLocale
? NextResponse.redirect(new URL(`/it${cleanPathName}`, request.url))
: undefined;
}
Integrazione nel next.config.js
Infine, importiamo la configurazione i18n nel file next.config.js
:
const { i18n } = require('./next-i18next.config');
const nextConfig = {
i18n, // Configurazione localizzazione
// altre configurazioni...
};
module.exports = nextConfig;
Come funziona la soluzione
La logica del middleware è elegante nella sua semplicità:
- Intercettazione: quando un utente visita la root
/
o qualsiasi URL senza prefisso di lingua, Next.js assegna automaticamente la lingua'default'
- Filtraggio: il middleware verifica che la richiesta non sia per file statici (immagini, CSS, JavaScript) o API routes, per evitare redirect non necessari
- Pulizia del pathname: su Vercel, il pathname può contenere
/default
, che viene rimosso per normalizzare l'URL - Redirect: se tutte le condizioni sono soddisfatte, l'utente viene reindirizzato alla lingua effettiva desiderata (in questo caso
/it
)
Gestione delle differenze ambiente locale vs Vercel
Una delle sfide principali di questa implementazione è la gestione delle differenze tra l'ambiente di sviluppo locale e la piattaforma Vercel. Durante lo sviluppo locale, il pathname rimane pulito, ma su Vercel può apparire /default
nel pathname del middleware.
Il codice gestisce questa differenza attraverso la pulizia condizionale:
const cleanPathName = request.nextUrl.pathname.startsWith('/default')
? request.nextUrl.pathname.replace('/default', '/').replace('//', '/')
: request.nextUrl.pathname;
Vantaggi di questo approccio
Prestazioni ottimizzate
Il redirect avviene a livello di server attraverso il middleware, risultando più veloce rispetto alle soluzioni client-side che potrebbero causare flickering o doppio caricamento della pagina.
SEO-friendly
I motori di ricerca ricevono un redirect 307 (temporaneo) pulito, che mantiene l'autorità del dominio e non penalizza il ranking. Inoltre, la gestione server-side evita problemi di indicizzazione.
Flessibilità
È facile cambiare la lingua di default modificando semplicemente l'URL di destinazione nel middleware. Non è necessario toccare la logica delle pagine o dei componenti.
Compatibilità
La soluzione funziona sia in ambiente locale, sia in ambiente server adeguatamente configurato per far girare Next.js, che su Vercel, risolvendo le inconsistenze che spesso si presentano tra i due ambienti.
Casi d'uso pratici
Questa soluzione è particolarmente utile per:
- Siti aziendali multilingue dove l'azienda opera principalmente in una lingua ma vuole offrire traduzioni
- E-commerce internazionali che vogliono mantenere URL puliti per il mercato principale
- Applicazioni SaaS con utenti globali ma focus su un mercato specifico
- Portfolio e blog personali di professionisti che operano in mercati multilingue
Considerazioni per l'implementazione
Testing
È fondamentale testare la soluzione sia in ambiente locale che su Vercel, verificando che i redirect funzionino correttamente per tutti i tipi di URL e che non interferiscano con:
- Asset statici
- API routes
- Sitemap e robots.txt
- Feed RSS
Performance monitoring
Monitora le prestazioni del middleware, specialmente in siti ad alto traffico. Anche se l'overhead è minimo, è buona pratica tenere sotto controllo i tempi di risposta.
Fallback strategy
Considera sempre una strategia di fallback nel caso in cui il middleware non funzioni come previsto. Potresti implementare un redirect client-side di emergenza.
Conclusioni
La gestione dell'internazionalizzazione in Next.js può presentare sfide specifiche, ma con il giusto approccio è possibile creare soluzioni eleganti e performanti. Il middleware personalizzato che ho presentato risolve efficacemente il problema della lingua di default senza prefisso, mantenendo la semplicità di configurazione e garantendo compatibilità tra diversi ambienti di deployment.
Questa soluzione si è dimostrata affidabile in diversi progetti di produzione e offre la flessibilità necessaria per adattarsi a varie esigenze di business. La chiave del successo sta nella comprensione delle specifiche del framework Next.js e nell'adattamento delle soluzioni esistenti alle proprie necessità.
Se stai lavorando su un progetto multilingue con Next.js e hai incontrato problemi simili, questa implementazione potrebbe essere esattamente quello di cui hai bisogno per creare un'esperienza utente fluida e ottimizzata per i motori di ricerca.