# General Translation Knowledge Base: Come aggiungo l'i18n a un'app Next.js con Pages Router?
URL: https://generaltranslation.com/it/kb/add-i18n-to-nextjs-pages-router.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Aggiungi un blocco i18n con locales e defaultLocale a next.config.js e Next.js servirà /es e /fr, reindirizzerà i visitatori in base alla lingua del browser e passerà l'impostazione regionale a getStaticProps e getServerSideProps. Una libreria renderizza i messaggi; gt-next di General Translation genera anche le traduzioni a partire dai testi scritti inline in JSX.
Category: Internazionalizzazione
Last updated: 2026-10-28
Authors: General Translation Team
Published: 2026-10-28

Il Pages Router offre un routing internazionalizzato integrato fin da Next.js 10: basta elencare le impostazioni regionali e quella predefinita nel blocco `i18n` di `next.config.js` e Next.js servirà ogni lingua al proprio URL, reindirizzerà chi visita il sito per la prima volta in base alla lingua del browser e passerà il locale attivo alle funzioni di recupero dei dati. Non carica, non renderizza e non traduce alcun testo: Next.js ha progettato il routing per funzionare insieme a una libreria i18n, quindi dovrai comunque scegliere una libreria per i messaggi e un modo per produrre le traduzioni ([internazionalizzazione nel Pages Router di Next.js](https://nextjs.org/docs/pages/guides/internationalization)).

## Cosa fa il routing i18n integrato

L&#39;intera funzionalità si riduce a un solo blocco di config:

```js title="next.config.js"
/** @type {import('next').NextConfig} */
module.exports = {
  i18n: {
    // Tutte le impostazioni regionali gestite dal sito, inclusa quella predefinita
    locales: ['en', 'es', 'fr'],
    // Servita senza prefisso: /about, /es/about, /fr/about
    defaultLocale: 'en',
  },
};
```

Con questa configurazione, Next.js svolge quattro compiti:

* **URL.** Il routing basato su sottopercorsi mantiene l&#39;impostazione locale predefinita su `/about` e aggiunge un prefisso alle altre (`/fr/about`). Per servire invece le impostazioni regionali da domini separati, come `example.fr`, aggiungi un elenco `domains`, con un `domain` e un `defaultLocale` per ogni voce.
* **Rilevamento.** Quando un utente visita `/`, Next.js legge l&#39;intestazione `Accept-Language` e reindirizza al prefisso o al dominio corrispondente. Un cookie `NEXT_LOCALE`, impostato dal tuo selettore della lingua, ha la precedenza sull&#39;intestazione. Imposta `localeDetection: false` per disattivare il reindirizzamento.
* **Impostazione regionale nel codice.** `useRouter()` restituisce `locale`, `locales` e `defaultLocale`. `getStaticProps` e `getServerSideProps` ricevono `locale` nel proprio contesto, mentre `getStaticPaths` riceve `locales`.
* **`<html lang>`.** Next.js imposta l&#39;attributo sul locale attivo, a meno che il tuo `_document` non ne specifichi uno proprio.

Tanto basta per implementare l&#39;i18n manualmente. Questa pagina carica un file JSON per ogni impostazione regionale in fase di compilazione:

```tsx title="pages/index.tsx"
import type { GetStaticProps, InferGetStaticPropsType } from 'next';
import Link from 'next/link';
import { useRouter } from 'next/router';

export const getStaticProps = (async ({ locale }) => {
  // In fase di compilazione, Next.js la chiama una volta per ogni impostazione regionale configurata.
  const messages = (await import(`../messages/${locale}.json`)).default;
  return { props: { messages } };
}) satisfies GetStaticProps;

export default function Home({ messages }: InferGetStaticPropsType<typeof getStaticProps>) {
  const { locales } = useRouter(); // ['en', 'es', 'fr']

  return (
    <main>
      <h1>{messages.title}</h1>
      <nav>
        {locales?.map((code) => (
          // La stessa pagina in ogni lingua: /, /es, /fr
          <Link key={code} href="/" locale={code} lang={code}>
            {new Intl.DisplayNames([code], { type: 'language' }).of(code)}
          </Link>
        ))}
      </nav>
    </main>
  );
}
```

Una build di produzione serve `/es` come `<html lang="es">` con l&#39;intestazione in spagnolo, mentre una richiesta a `/` con `Accept-Language: fr-CA` riceve un reindirizzamento 307 a `/fr`. I link mostrano il nome di ciascuna lingua nella lingua stessa (English, español, français), come dovrebbe fare qualsiasi [selettore della lingua](/kb/language-switcher).

### Cosa resta a carico tuo

Il routing si ferma all&#39;URL. Plurali, formattazione di numeri e date e interpolazione delle stringhe spettano a una libreria, così come mantenere sincronizzati i file dei messaggi man mano che i componenti cambiano. Inoltre, Next.js non aggiunge i link `hreflang` tra le diverse versioni linguistiche: devi aggiungerli tu con `next/head`. (Vedi [Cos&#39;è hreflang?](/kb/what-is-hreflang).) E niente di tutto questo produce una traduzione.

In fase di pianificazione, tieni conto di tre limiti:

* **Nessuna esportazione statica.** Il routing internazionalizzato non funziona con `output: 'export'`, perché si basa sul livello di routing di Next.js.
* **La fase di compilazione si allunga a ogni impostazione regionale.** Ogni pagina `getStaticProps` non dinamica viene compilata una volta per ciascuna impostazione regionale, quindi 50 impostazioni regionali e 10 pagine equivalgono a 500 chiamate. Le route dinamiche devono restituire ogni impostazione regionale da `getStaticPaths`, altrimenti Next.js compila solo quella predefinita.
* **Limiti massimi.** `locales` e `domains` possono contenere al massimo 100 voci ciascuno.

### Non è disponibile nell&#39;App Router

La config `i18n` è una funzionalità del Pages Router. Nell&#39;App Router, `useRouter` di `next/navigation` non espone più `locale`, `locales` e `defaultLocale`, e secondo Next.js le sue funzionalità i18n integrate non servono nella directory `app` ([guida alla migrazione](https://nextjs.org/docs/app/guides/migrating/app-router-migration#step-5-migrating-routing-hooks)). Le app basate sull&#39;App Router inseriscono invece l&#39;impostazione regionale in un segmento `[locale]` oppure la risolvono nel middleware. (Vedi [Come aggiungo l&#39;i18n a un&#39;app Next.js con App Router?](/kb/add-i18n-to-nextjs).)

## Librerie che renderizzano i messaggi

| Libreria                                                                   | Configurazione del Pages Router                                                                                                                                   | Come scrivi i testi                                                                                                                        | Da dove arrivano le traduzioni                                                                         |
| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| [next-i18next](https://github.com/i18next/next-i18next#pages-router-setup) | `appWithTranslation` racchiude `_app`; `serverSideTranslations(locale, ['common'])` in `getStaticProps` o `getServerSideProps`, importato da `next-i18next/pages` | Chiavi in namespace JSON, renderizzate con `t('title')`                                                                                    | Tu, i traduttori o un sistema di gestione delle traduzioni (TMS) come Locize                           |
| [next-intl](https://next-intl.dev/docs/getting-started/pages-router)       | `NextIntlClientProvider` in `_app`, con i `messages` restituiti da `getStaticProps`                                                                               | Chiavi in un file JSON per ogni impostazione regionale, renderizzate con [`useTranslations`](/docs/react/reference/hooks/use-translations) | Tu o i tuoi traduttori                                                                                 |
| [react-intl](https://formatjs.github.io/docs/react-intl)                   | `IntlProvider` in `_app`, a cui vengono passati il locale attivo e i relativi messaggi                                                                            | Messaggi ICU inline come `defaultMessage`, estratti con `formatjs extract`                                                                 | Tu, i traduttori o un TMS                                                                              |
| General Translation (`gt-next`)                                            | `withGTServerSideProps` o `withGTStaticProps` su ogni pagina; [`GTProvider`](/docs/react/reference/components/gt-provider) in `_app`                              | JSX racchiuso in [`<T>`](/docs/react/reference/components/t), stringhe con [`useGT`](/docs/react/reference/hooks/use-gt)                   | Generate da [`npx gt translate`](/docs/cli/reference/commands/translate) e revisionate nella Dashboard |

next-i18next 16 supporta entrambi i router e mantiene la consueta API per il Pages Router in `next-i18next/pages`. La documentazione di next-intl consiglia l&#39;App Router, ma il Pages Router resta pienamente supportato. Nel Pages Router, entrambe si affiancano al blocco `i18n` visto sopra per la gestione degli URL e il rilevamento della lingua.

Usa next-i18next se hai già dei namespace i18next o vuoi sfruttarne l&#39;ecosistema di plugin. Usa next-intl se prevedi di passare all&#39;App Router e vuoi la stessa API prima e dopo la migrazione. Usa react-intl se i tuoi messaggi sono stringhe ICU con cui i traduttori lavorano già. Usa General Translation se preferisci mantenere i testi inline nei componenti e lasciare che le traduzioni vengano generate, revisionate e aggiornate di pari passo con il codice. (Consulta [next-intl vs. gt-next](/kb/next-intl-vs-gt-next) per un confronto dettagliato.)

Se resti su next-i18next o next-intl, la CLI di General Translation può comunque tradurre i loro file JSON, comprese le stringhe ICU, senza alcuna migrazione ([traduzione di file JSON](/docs/cli/reference/formats/json-files)).

## Aggiungere General Translation a un&#39;app con Pages Router

Questa configurazione aggiunge lo spagnolo e il francese a un&#39;app con Pages Router, assegnando a ciascuna lingua un proprio URL. È stata testata con un&#39;app creata con `create-next-app` 16.4.3 (`--no-app`), Next.js 16.4.3, `gt-next@11.4.16` e `gt@2.26.11`. `gt-next` supporta Next.js 13.0.0 e versioni successive, ad eccezione della 15.2.1 e della 15.2.2. Il suo entry point `gt-next/server` è compatibile solo con App Router.

### 1. Installa la libreria e la CLI

```bash
npm install gt-next@11.4.16
npm install --save-dev gt@2.26.11
```

### 2. Imposta le lingue

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["en", "es", "fr"],
  "files": {
    "gt": {
      "output": "public/_gt/[locale].json"
    }
  }
}
```

Mantieni `en` in `locales`: lo stesso elenco viene usato anche dal blocco `i18n` di Next.js, che richiede l&#39;impostazione locale predefinita.

### 3. Attiva il routing i18n di Next.js

```ts title="next.config.ts"
import type { NextConfig } from 'next';
import { withGTConfig } from 'gt-next/config';
import gtConfig from './gt.config.json';

const nextConfig: NextConfig = {
  i18n: {
    locales: gtConfig.locales,
    defaultLocale: gtConfig.defaultLocale,
  },
};

export default withGTConfig(nextConfig);
```

Next.js gestisce il routing e il rilevamento descritti sopra. Non servono il middleware di `gt-next` né una cartella `pages/[locale]`.

`create-next-app` genera `<Html lang="en">` in `pages/_document.tsx`, che sovrascrive l&#39;impostazione regionale: nell&#39;app di test, `/es` restituiva `lang="en"` pur mostrando il testo in spagnolo. Rimuovi la prop per lasciare che sia Next.js a impostarla:

```tsx title="pages/_document.tsx"
import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
```

### 4. Caricare le traduzioni da file locali

```ts title="loadTranslations.ts"
export default async function loadTranslations(locale: string) {
  try {
    const translations = await import(`./public/_gt/${locale}.json`);
    return translations.default;
  } catch {
    // Finché i file non esistono, renderizza il testo di origine
    return {};
  }
}
```

`withGTConfig` individua `loadTranslations.ts` nella radice del progetto o in `src/`. Le traduzioni vengono incluse nella build, quindi a runtime l&#39;app non effettua alcuna chiamata a General Translation. (Vedi [archiviazione delle traduzioni](/docs/react/guides/storing-translations).)

### 5. Passa l&#39;impostazione regionale e le traduzioni a ogni pagina

Racchiudi la funzione di recupero dati di ogni pagina. Il wrapper legge `context.locale` da Next.js e aggiunge `locale` e `translations` alle props della pagina:

```tsx title="pages/about.tsx"
import { T, withGTStaticProps } from 'gt-next';

// Next.js esegue la build di questa pagina una volta per ogni impostazione regionale.
export const getStaticProps = withGTStaticProps();

export default function About() {
  return (
    <T>
      <h1>About us</h1>
    </T>
  );
}
```

Usa `withGTServerSideProps()` allo stesso modo nelle pagine server-rendered. Entrambe accettano come argomento la tua funzione di recupero dati, ad esempio `withGTStaticProps(async (context) => ({ props: { posts } }))`, e restituiscono invariato un eventuale risultato `redirect` o `notFound`. Racchiudi ogni pagina che renderizza contenuto tradotto.

Quindi passa queste props a [`GTProvider`](/docs/react/reference/components/gt-provider) in `_app`:

```tsx title="pages/_app.tsx"
import type { AppProps } from 'next/app';
import Router from 'next/router';
import { GTProvider, type WithGTServerSideProps } from 'gt-next';

export default function App({ Component, pageProps }: AppProps<WithGTServerSideProps>) {
  const { locale, translations } = pageProps;

  return (
    <GTProvider
      locale={locale}
      translations={translations}
      // Cambia lingua tramite la navigazione di Next.js: /es, /fr e ritorno a /
      _reload={({ locale: nextLocale }) => {
        void Router.push(Router.pathname, Router.asPath, { locale: nextLocale });
      }}
    >
      <Component {...pageProps} />
    </GTProvider>
  );
}
```

### 6. Contrassegnare i contenuti da tradurre

```tsx title="pages/index.tsx"
import { LocaleSelector, T, useGT, withGTServerSideProps } from 'gt-next';

export const getServerSideProps = withGTServerSideProps();

export default function Home() {
  const gt = useGT();

  return (
    <main>
      <LocaleSelector />
      <T>
        <h1>Find your next project</h1>
        <p>Explore projects from teams around the world.</p>
      </T>
      <input type="search" placeholder={gt('Search projects')} aria-label={gt('Search projects')} />
    </main>
  );
}
```

[`<T>`](/docs/react/reference/components/t) traduce insieme il titolo e il paragrafo, usando il loro markup come contesto. [`useGT`](/docs/react/reference/hooks/use-gt) gestisce le stringhe degli attributi. [`<LocaleSelector>`](/docs/react/reference/components/locale-selector) elenca le tue impostazioni regionali, ciascuna con il nome nella propria lingua. Selezionando Español viene salvato `NEXT_LOCALE=es`, che Next.js legge alla visita successiva di `/`, e la callback `_reload` reindirizza la pagina a `/es`.

### 7. Genera traduzioni e verifica la build

Accedi con [`npx gt login`](/docs/cli/reference/commands/login), imposta `GT_PROJECT_ID` ed esegui [`npx gt translate`](/docs/cli/reference/commands/translate) per generare `public/_gt/es.json` e `fr.json`. Per provare la configurazione senza un account, puoi usare [`npx gt generate`](/docs/cli/reference/commands/generate), che crea gli stessi file con il testo di origine in inglese, da tradurre manualmente.

Nell&#39;app di test, con il file spagnolo compilato, `next build` è andato a buon fine e `next start` ha servito:

* `/` come `<html lang="en">` con l&#39;intestazione in inglese
* `/es` come `<html lang="es">` con l&#39;intestazione e il segnaposto in spagnolo
* `/es/about`, generata con `withGTStaticProps`, in spagnolo
* `/` con `Accept-Language: es` come reindirizzamento 307 verso `/es`

## Pubblicare e mantenere aggiornate le traduzioni

Esegui la traduzione prima di ogni build, così i nuovi testi vengono pubblicati in tutte le lingue:

```json title="package.json"
{
  "scripts": {
    "build": "gt validate && gt translate && next build"
  }
}
```

Nel tuo provider di hosting, imposta `GT_PROJECT_ID` e una chiave API di progetto come `GT_API_KEY` con i permessi **File &gt; Scrittura** e **Coda di traduzione &gt; Abilitata**. Mantieni la chiave server-side e non aggiungerle mai il prefisso `NEXT_PUBLIC_`. Se la build rigenera `public/_gt/` a ogni esecuzione, aggiungi la cartella a `.gitignore`. [`gt validate`](/docs/cli/reference/commands/validate) fa fallire la build, prima di qualsiasi chiamata API, se trova contenuti che comprometterebbero la traduzione; le esecuzioni successive traducono solo il contenuto sorgente nuovo o modificato.

I revisori possono modificare qualsiasi traduzione nell&#39;[Editor di traduzione](/docs/platform/dashboard/guides/reviewing-translations) di General Translation, mentre un [gruppo di contesto](/docs/platform/dashboard/guides/defining-context-for-translations) mantiene i termini del Glossario e il tono coerenti con gli altri tuoi progetti. Per rendere indicizzabili le versioni linguistiche, aggiungi `hreflang`, URL canonical e titoli tradotti: la guida [SEO multilingue per Next.js](/kb/multilingual-nextjs-seo) li illustra uno per uno.

## Domande frequenti

### L&#39;opzione i18n di next.config.js funziona con l&#39;App Router?

No. È una funzionalità del Pages Router: le app basate sull&#39;App Router utilizzano un segmento di route `[locale]` o un middleware, e `gt-next` prevede una configurazione specifica per l&#39;App Router, descritta nella documentazione.

### Posso usare getStaticProps con gt-next?

Sì. Racchiudila con `withGTStaticProps` e Next.js genererà una versione della pagina per ogni impostazione regionale. Per le route dinamiche, `getStaticPaths` deve comunque restituire un percorso per ogni impostazione regionale.

### Serve un middleware per l&#39;i18n con il Pages Router?

No. Next.js risolve l&#39;impostazione regionale dall&#39;URL, dal cookie `NEXT_LOCALE` e dall&#39;header `Accept-Language` prima che vengano eseguite le tue funzioni di recupero dati.

## Punti chiave

* Il blocco `i18n` in `next.config.js` fornisce al Pages Router gli URL per impostazione regionale, i reindirizzamenti basati su `Accept-Language` su `/`, il cookie `NEXT_LOCALE` e `locale` in `useRouter()` e nelle funzioni di recupero dati.
* Non renderizza né traduce i messaggi, non aggiunge `hreflang`, non funziona con `output: 'export'` e non si applica all&#39;App Router.
* Rimuovi il `lang="en"` hardcoded da `pages/_document.tsx`, altrimenti l&#39;HTML di ogni impostazione regionale dichiarerà l&#39;inglese.
* next-i18next, next-intl e react-intl renderizzano le traduzioni che fornisci tu; `gt-next` di General Translation, invece, le genera anche, con `withGTStaticProps` o `withGTServerSideProps` in ogni pagina e [`GTProvider`](/docs/react/reference/components/gt-provider) in `_app`.
* Aggiungi [`gt validate && gt translate`](/docs/cli/reference/commands/validate) prima di `next build`, così ogni rilascio sarà disponibile in tutte le lingue.

## Related questions

- [Come si aggiunge l'i18n a un'app Next.js con App Router?](https://generaltranslation.com/it/kb/add-i18n-to-nextjs.mdx): Inizia con gt init per configurare General Translation in un progetto App Router supportato, poi contrassegna il contenuto di origine, genera le traduzioni e verifica il cambio di lingua. gt-next mantiene i testi nel JSX insieme al contesto di traduzione; la CLI, l'editor della Dashboard e Locadex si occupano di generazione, revisione e aggiornamenti continui. Questa guida mostra anche la configurazione esplicita con file locali.
- [Alternative a next-intl: gt-next vs. next-intl](https://generaltranslation.com/it/kb/next-intl-vs-gt-next.mdx): next-intl renderizza le traduzioni che fornisci in un catalogo di messaggi per ciascuna lingua. Anche gt-next renderizza le traduzioni, ma in più General Translation le genera a partire dai testi scritti inline nel tuo JSX. Entrambi sono rilasciati con licenza MIT e supportano l'App Router e i Componenti server. Se i tuoi cataloghi next-intl funzionano già, puoi mantenerli e usare General Translation per tradurli senza alcuna migrazione.
- [Come si configura la SEO per un'app Next.js multilingue?](https://generaltranslation.com/it/kb/multilingual-nextjs-seo.mdx): Assegna a ogni lingua un proprio URL con prefisso, come /en/about e /es/about, quindi pubblica html lang, un canonical autoreferenziale, alternative hreflang con x-default, un titolo e una descrizione tradotti e una voce nella mappa del sito per ogni lingua pubblicata. Contrassegna con noindex le versioni non pubblicate. gt-next di General Translation instrada ogni lingua verso il proprio URL e traduce i titoli con getGT.
- [Best practice per il selettore della lingua: UX, SEO e accessibilità](https://generaltranslation.com/it/kb/language-switcher.mdx): Indica ogni lingua con il suo nome nativo, ad esempio Deutsch o 日本語, ed evita le bandiere, che rappresentano paesi. Collega ogni opzione alla stessa pagina in quella lingua tramite un link scansionabile, memorizza la scelta in un cookie e non reindirizzare mai automaticamente un URL localizzato.
- [Alternative a i18next: General Translation vs. i18next](https://generaltranslation.com/it/kb/general-translation-vs-i18next.mdx): Scegli General Translation per mantenere i testi inline nei componenti React e generare le traduzioni sfruttando la struttura JSX e il contesto del prodotto. In alternativa, puoi continuare a usare i18next e affidarti a General Translation per tradurre i cataloghi esistenti. i18next si occupa del rendering dei messaggi e della selezione dei plurali, mentre la generazione delle traduzioni è affidata a un servizio separato.

## Previous and next questions

- Previous question: [Che cos'è la memoria di traduzione e serve ancora con l'IA?](https://generaltranslation.com/it/kb/what-is-translation-memory.mdx)
- Next question: [Come mantenere coerente la terminologia nella traduzione con l'AI?](https://generaltranslation.com/it/kb/ai-translation-glossary.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/it/kb/sitemap.md) for every article.
