# General Translation Knowledge Base: Come si configura la SEO per un'app Next.js multilingue?
URL: https://generaltranslation.com/it/kb/multilingual-nextjs-seo.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Assegna a ogni lingua un URL dedicato, imposta l'attributo lang del tag html, fai puntare l'URL canonical di ogni pagina alla pagina stessa, aggiungi le alternative hreflang per ogni lingua, traduci titoli e descrizioni ed elenca tutte le versioni linguistiche nella sitemap.
Category: SEO multilingue
Last updated: 2026-02-17
Authors: General Translation Team
Published: 2026-02-17

## Video

The video is narrated in English, with English captions.

[How do I set up SEO for a multilingual Next.js app?](https://caxecubb9c64cezv.public.blob.vercel-storage.com/films/kb-multilingual-nextjs-seo.mp4) (50 s)

General Translation lets you give every language its own URL and tell search engines about them. Move your pages into `app/[locale]` with `gt-next`'s middleware, set the html `lang` attribute with `useLocale`, add canonical and hreflang links with a helper, translate the title with `getGT`, and list every page in every language in a sitemap.

## Perché la SEO multilingue richiede un&#39;attenzione particolare

La maggior parte degli sviluppatori che aggiungono l&#39;i18n alla propria app Next.js si limita a tradurre la UI e considera il lavoro concluso.
Ma se i motori di ricerca non riescono a trovare, indicizzare e associare correttamente le diverse versioni linguistiche,
tutto quel lavoro di traduzione resta invisibile.

Un sito multilingue senza un&#39;adeguata configurazione SEO va incontro a diversi problemi:

* Google potrebbe indicizzare solo una versione linguistica e ignorare le altre
* Chi effettua ricerche in spagnolo si vede proporre la pagina in inglese
* Penalizzazioni per contenuti duplicati, perché Google considera `/en/about` e `/fr/about` come la stessa pagina
* Lingua errata negli snippet dei risultati di ricerca

**La buona notizia:** impostare correttamente la SEO multilingue in Next.js non è complicato.
Ci sono sei aspetti da curare e questa guida li affronta tutti utilizzando [`gt-next`](/docs/react/nextjs-quickstart).

***

## 1. Routing degli URL locale-based

Alla base della SEO multilingue c&#39;è un URL distinto per ogni lingua.
I motori di ricerca hanno bisogno di URL separati e scansionabili per indicizzare ciascuna versione linguistica in modo indipendente.

In altre parole, serve l&#39;**impostazione regionale nell&#39;URL**: non i cookie, non i parametri di query e nemmeno il solo rilevamento tramite `Accept-Language`.

```text
✅ generaltranslation.com/en/about
✅ generaltranslation.com/fr/about
✅ generaltranslation.com/es/about

❌ generaltranslation.com/about?lang=fr
❌ generaltranslation.com/about (con l'impostazione regionale salvata in un cookie)
```

### Configurare il routing delle impostazioni regionali con gt-next

Per prima cosa, sposta le tue pagine all&#39;interno di un segmento dinamico `[locale]`:

```text
app/
└── [locale]/
    ├── layout.tsx
    ├── page.tsx
    └── about/
        └── page.tsx
```

Poi crea il middleware nella radice del progetto (`proxy.ts` per Next.js 16+ oppure `middleware.ts` per Next.js 15 e versioni precedenti):

```ts title="proxy.ts"
import { createNextMiddleware } from 'gt-next/middleware';

export default createNextMiddleware();

export const config = {
  matcher: ['/((?!api|static|.*\\..*|_next).*)'],
};
```

In questo modo ottieni automaticamente URL con il prefisso dell&#39;impostazione regionale.
Per impostazione predefinita, l&#39;impostazione locale predefinita (ad esempio, l&#39;inglese) non ha alcun prefisso: `/about` resta pulito,
mentre gli utenti spagnoli vedono `/es/about` e quelli francesi `/fr/about`.

***

## 2. Impostare l&#39;attributo HTML `lang`

L&#39;attributo `lang` del tag `<html>` indica a browser e motori di ricerca in quale lingua è scritta la pagina.
È uno degli accorgimenti più semplici ed efficaci per migliorare accessibilità e SEO.

Senza questo attributo, gli screen reader cercano di indovinare la lingua (spesso sbagliando) e i motori di ricerca sono meno sicuri nell&#39;identificare la lingua della pagina.

{/* useLocale funziona sia nei componenti renderizzati sul client sia in quelli renderizzati sul server, ma non nei componenti asincroni */}

gt-next mette a disposizione l&#39;hook [`useLocale`](/docs/react/reference/hooks/use-locale), che rende questa operazione semplicissima nel tuo layout radice:

```tsx title="app/[locale]/layout.tsx"
import { useLocale, GTProvider } from 'gt-next';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const locale = useLocale();

  return (
    <html lang={locale}>
      <body>
        <GTProvider>
          {children}
        </GTProvider>
      </body>
    </html>
  );
}
```

[`useLocale`](/docs/react/reference/hooks/use-locale) restituisce il codice locale BCP 47 (ad es. `en-US`, `ar`, `zh-Hans`).

***

## 3. URL canonical

I tag canonical indicano ai motori di ricerca quale URL rappresenta la versione &quot;principale&quot; di una pagina.
Nei siti multilingue, ogni versione linguistica dovrebbe indicare se stessa come URL canonical:

```html
<!-- Nella pagina /fr/about -->
<link rel="canonical" href="https://example.com/fr/about" />
```

In questo modo i motori di ricerca non considereranno la tua pagina in francese un duplicato di quella in inglese.

In Next.js, gli URL canonical si impostano tramite l&#39;[API dei metadati](https://nextjs.org/docs/app/api-reference/functions/generate-metadata).
Usala insieme a [`getLocale`](/docs/react/nextjs/reference/functions/get-locale) di gt-next per generare l&#39;URL canonical corretto per ogni impostazione regionale:

```tsx title="app/[locale]/about/page.tsx"
import { getLocale } from 'gt-next/server';

const BASE_URL = 'https://example.com';

export async function generateMetadata() {
  const locale = await getLocale();

  return {
    alternates: {
      canonical: `${BASE_URL}/${locale}/about`,
    },
  };
}

export default function AboutPage() {
  return <h1>About Us</h1>;
}
```

Per l&#39;impostazione locale predefinita senza prefisso, apporta le modifiche necessarie:

```tsx
import { getDefaultLocale } from 'gt-next';
import { getLocale } from 'gt-next/server';

export async function generateMetadata() {
  const locale = await getLocale();
  const defaultLocale = getDefaultLocale();
  const path = '/about';

  const prefix = locale === defaultLocale ? '' : `/${locale}`;

  return {
    alternates: {
      canonical: `${BASE_URL}${prefix}${path}`,
    },
  };
}
```

***

## 4. Tag hreflang

I tag hreflang sono il segnale SEO multilingue più importante.
Indicano ai motori di ricerca: &quot;questa pagina esiste anche in queste altre lingue, ed ecco i relativi URL&quot;.

Senza hreflang, Google deve indovinare quale versione linguistica mostrare nei risultati di ricerca, e spesso sbaglia.

```html
<link rel="alternate" hreflang="en" href="https://example.com/about" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/about" />
<link rel="alternate" hreflang="es" href="https://example.com/es/about" />
<link rel="alternate" hreflang="x-default" href="https://example.com/about" />
```

Il tag `x-default` indica ai motori di ricerca quale URL mostrare quando nessuna delle lingue specificate corrisponde a quella dell&#39;utente.

In Next.js, puoi aggiungere hreflang tramite la proprietà `alternates.languages` dell&#39;API dei metadati.
Ecco un helper riutilizzabile compatibile con gt-next:

```tsx title="lib/i18n-metadata.ts"
import { getDefaultLocale } from 'gt-next';
import { getLocale } from 'gt-next/server';

const BASE_URL = 'https://example.com';
const SUPPORTED_LOCALES = ['en', 'fr', 'es'];

export async function getI18NMetadata(path: string) {
  const locale = await getLocale();
  const defaultLocale = getDefaultLocale();

  const getUrl = (loc: string) => {
    const prefix = loc === defaultLocale ? '' : `/${loc}`;
    return `${BASE_URL}${prefix}${path}`;
  };

  const languages: Record<string, string> = {};
  for (const loc of SUPPORTED_LOCALES) {
    languages[loc] = getUrl(loc);
  }
  languages['x-default'] = getUrl(defaultLocale);

  return {
    alternates: {
      canonical: getUrl(locale),
      languages,
    },
  };
}
```

Quindi usalo in qualsiasi pagina:

```tsx title="app/[locale]/about/page.tsx"
import { getI18NMetadata } from '@/lib/i18n-metadata';

export async function generateMetadata() {
  return await getI18NMetadata('/about');
}
```

In questo modo si generano sia il tag canonical sia tutti i tag hreflang con un&#39;unica chiamata.

***

## 5. Metadati tradotti

I motori di ricerca mostrano nei risultati il titolo e la descrizione della tua pagina.
Se una pagina in francese ha titolo e descrizione in inglese, gli utenti saranno meno propensi a cliccare, e Google potrebbe penalizzarla nel posizionamento.

Usa la funzione [`getGT`](/docs/react/nextjs/reference/functions/get-gt) di gt-next per tradurre le stringhe dei metadati:

```tsx title="app/[locale]/about/page.tsx"
import { getGT } from 'gt-next/server';
import { getI18NMetadata } from '@/lib/i18n-metadata';

export async function generateMetadata() {
  const t = await getGT();
  const i18nMeta = await getI18NMetadata('/about');

  return {
    title: t('About Us'),
    description: t('Learn about our mission and team.'),
    ...i18nMeta,
  };
}
```

In questo modo ottieni titoli e descrizioni localizzati nei risultati di ricerca,
migliorando sensibilmente la percentuale di clic (CTR) per le query in lingue diverse dall&#39;inglese.

***

## 6. Sitemap multilingue

Una sitemap aiuta i motori di ricerca a individuare tutte le tue pagine, incluse le varie versioni linguistiche.
Per i siti multilingue, è consigliabile includere nella sitemap anche le annotazioni hreflang.

Next.js supporta le [sitemap generate programmaticamente](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap) tramite un file `sitemap.ts`:

```ts title="app/sitemap.ts"
import { MetadataRoute } from 'next';

const BASE_URL = 'https://example.com';
const LOCALES = ['en', 'fr', 'es'];
const DEFAULT_LOCALE = 'en';
const PAGES = ['/', '/about', '/blog', '/contact'];

export default function sitemap(): MetadataRoute.Sitemap {
  return PAGES.flatMap((path) => {
    const getUrl = (locale: string) => {
      const prefix = locale === DEFAULT_LOCALE ? '' : `/${locale}`;
      return `${BASE_URL}${prefix}${path === '/' ? '' : path}`;
    };

    const languages: Record<string, string> = {};
    for (const locale of LOCALES) {
      languages[locale] = getUrl(locale);
    }

    return LOCALES.map((locale) => ({
      url: getUrl(locale),
      lastModified: new Date(),
      alternates: { languages },
    }));
  });
}
```

In questo modo viene generata una sitemap con una voce per ogni pagina in ciascuna impostazione regionale,
e ogni voce include annotazioni hreflang che puntano a tutte le versioni linguistiche.

***

## Checklist

Ecco un breve riepilogo di quanto trattato:

| Requisito SEO                       | Implementazione                                                                                                                  |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Impostazione regionale nell&#39;URL | [`createNextMiddleware()`](/docs/react/nextjs/reference/functions/create-next-middleware) con il segmento dinamico `[locale]`    |
| Attributo HTML `lang`               | [`useLocale()`](/docs/react/reference/hooks/use-locale) nel layout radice                                                        |
| URL canonical                       | [`getLocale()`](/docs/react/nextjs/reference/functions/get-locale) + `alternates.canonical` dell&#39;API dei metadati di Next.js |
| Tag hreflang                        | `alternates.languages` dell&#39;API dei metadati di Next.js con tutte le impostazioni regionali supportate                       |
| Metadati tradotti                   | [`getGT()`](/docs/react/nextjs/reference/functions/get-gt) per titoli e descrizioni delle pagine                                 |
| Sitemap multilingue                 | `sitemap.ts` con voci per ciascuna impostazione regionale e alternative hreflang                                                 |

***

Segui l&#39;[Avvio rapido di `gt-next`](/docs/react/nextjs-quickstart) per configurare l&#39;intero stack di internazionalizzazione. Configura poi il routing con la [Guida al middleware](/docs/react/nextjs/app-router-middleware), genera pagine multilingue con la [Generazione di Siti Statici](/docs/react/nextjs/app-router-static-site-generation) e aggiungi il [supporto right-to-left](/docs/react/guides/managing-locales).

## Related questions

- [Posso fare i18n senza file di traduzione?](https://generaltranslation.com/it/kb/i18n-without-translation-files.mdx): Sì. Con gt-react o gt-next, i contenuti restano inline nei tuoi componenti, all'interno di un componente `<T>`, e le traduzioni vengono generate come output in fase di compilazione. Non ci sono quindi chiavi né file JSON per ogni impostazione regionale da scrivere e mantenere sincronizzati.
- [Qual è il miglior software di localizzazione per gli sviluppatori?](https://generaltranslation.com/it/kb/best-localization-software.mdx): Cerca un unico sistema che copra l'intera pipeline, dalla libreria i18n nel tuo codice fino alla traduzione e alla consegna, invece di mettere insieme una libreria, un sistema di gestione delle traduzioni e un fornitore di traduzioni separati.
- [Qual è la migliore libreria i18n per un'app React?](https://generaltranslation.com/it/kb/best-react-i18n-library.mdx): Le quattro principali librerie i18n per React sono gt-react di General Translation, react-i18next, Lingui e React Intl. Tutte e quattro renderizzano e formattano le traduzioni, ma solo gt-react è anche in grado di generarle, a partire dai testi scritti inline nel tuo JSX. Scegli react-i18next per continuare a usare i cataloghi e i plugin di i18next, Lingui per l'estrazione in cataloghi compilati e React Intl per FormatJS e ICU MessageFormat.

## Previous and next questions

- Previous question: [Come si traduce il testo condizionale in JSX?](https://generaltranslation.com/it/kb/translate-conditional-jsx.mdx)
- Next question: [Qual è il miglior software di localizzazione per gli sviluppatori?](https://generaltranslation.com/it/kb/best-localization-software.mdx)

## Sitemap

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