Sviluppo

Gestire l'i18n in Next.js: il redirect automatico dalla root

Come risolvere il problema della lingua di default senza prefisso in Next.js con un middleware personalizzato e una configurazione i18n ottimizzata.

Gestire l'i18n in Next.js: il redirect automatico dalla root
I punti chiave

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à:

  1. Intercettazione: quando un utente visita la root / o qualsiasi URL senza prefisso di lingua, Next.js assegna automaticamente la lingua 'default'
  2. Filtraggio: il middleware verifica che la richiesta non sia per file statici (immagini, CSS, JavaScript) o API routes, per evitare redirect non necessari
  3. Pulizia del pathname: su Vercel, il pathname può contenere /default, che viene rimosso per normalizzare l'URL
  4. 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.

Rimani aggiornato con gli articoli del mio magazine anche su LinkedIn!
I punti chiave