Il contenuto di questa pagina è stato tradotto con un'IA.
Vedi l'ultima versione del contenuto originale in ingleseIniziare con l'internazionalizzazione (i18n) usando Intlayer e Next.js con Page Router
Cos'è Intlayer?
Intlayer è una libreria innovativa e open-source per l'internazionalizzazione (i18n) progettata per semplificare il supporto multilingue nelle moderne applicazioni web. Intlayer si integra perfettamente con l'ultima versione del framework Next.js, incluso il suo tradizionale Page Router.
Con Intlayer, puoi:
- Gestire facilmente le traduzioni utilizzando dizionari dichiarativi a livello di componente.
- Localizzare dinamicamente i metadata, le rotte e i contenuti.
- Garantire il supporto a TypeScript con tipi autogenerati, migliorando l'autocompletamento e il rilevamento degli errori.
- Beneficiare di funzionalità avanzate, come il rilevamento e il cambio dinamico della lingua.
Intlayer è compatibile con Next.js 12, 13, 14 e 15. Se stai utilizzando Next.js App Router, consulta la guida all'App Router. Per Next.js 15, segui questa guida.
Guida passo-passo per configurare Intlayer in un'applicazione Next.js usando Page Router
Passo 1: Installa le dipendenze
Installa i pacchetti necessari usando il tuo gestore di pacchetti preferito:
npm install intlayer next-intlayer
intlayer
intlayer
Il pacchetto principale che fornisce strumenti di internazionalizzazione per la gestione della configurazione, la traduzione, la dichiarazione dei contenuti, la traspilazione e i comandi CLI.
next-intlayer
Il pacchetto che integra Intlayer con Next.js. Fornisce provider di contesto e hook per l'internazionalizzazione in Next.js. Inoltre, include il plugin Next.js per integrare Intlayer con Webpack o Turbopack, così come middleware per rilevare la lingua preferita dall'utente, gestire i cookie e gestire il reindirizzamento degli URL.
Passo 2: Configura il tuo progetto
Crea un file di configurazione per definire le lingue supportate dalla tua applicazione:
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, // Aggiungi qui le altre tue localizzazioni ], defaultLocale: Locales.ENGLISH, },};export default config;
Attraverso questo file di configurazione, puoi impostare URL localizzati, reindirizzamenti middleware, nomi dei cookie, la posizione e l'estensione delle tue dichiarazioni di contenuto, disabilitare i log di Intlayer nella console e altro ancora. Per un elenco completo dei parametri disponibili, consulta la documentazione di configurazione.
Passo 3: Integrare Intlayer con la Configurazione di Next.js
Modifica la configurazione di Next.js per incorporare Intlayer:
import { withIntlayer } from "next-intlayer/server";/** @type {import('next').NextConfig} */const nextConfig = { // La tua configurazione esistente di Next.js};export default withIntlayer(nextConfig);
Il plugin Next.js withIntlayer() viene utilizzato per integrare Intlayer con Next.js. Garantisce la costruzione dei file di dichiarazione del contenuto e li monitora in modalità sviluppo. Definisce le variabili d'ambiente di Intlayer all'interno degli ambienti Webpack o Turbopack. Inoltre, fornisce alias per ottimizzare le prestazioni e assicura la compatibilità con i componenti server.
Passo 4: Configurare il Middleware per il Rilevamento della Lingua
Configura il middleware per rilevare automaticamente e gestire la lingua preferita dall'utente:
export { intlayerMiddleware as middleware } from "next-intlayer/middleware";export const config = { matcher: "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};
Adatta il parametro matcher per corrispondere alle rotte della tua applicazione. Per maggiori dettagli, consulta la documentazione di Next.js sulla configurazione del matcher.
Passo 5: Definire le Rotte Dinamiche per la Localizzazione
Implementa il routing dinamico per fornire contenuti localizzati in base alla lingua dell'utente.
Crea Pagine Specifiche per la Lingua:
Rinomina il file della tua pagina principale per includere il segmento dinamico [locale].
bashmv src/pages/index.tsx src/pages/[locale]/index.tsx
Aggiorna _app.tsx per Gestire la Localizzazione:
Modifica il file _app.tsx per includere i provider di Intlayer.
src/pages/_app.tsximport type { FC } from "react";import type { AppProps } from "next/app";import { IntlayerClientProvider } from "next-intlayer";const App = FC<AppProps>({ Component, pageProps }) => { const { locale } = pageProps; return ( <IntlayerClientProvider locale={locale}> <Component {...pageProps} /> </IntlayerClientProvider> );}export default MyApp;
Configurare getStaticPaths e getStaticProps:
Nel tuo file [locale]/index.tsx, definisci i percorsi e le proprietà per gestire le diverse localizzazioni.
src/pages/[locale]/index.tsximport type { FC } from "react";import type { GetStaticPaths, GetStaticProps } from "next";import { type Locales, getConfiguration } from "intlayer";const HomePage: FC = () => <div>{/* Il tuo contenuto qui */}</div>;export const getStaticPaths: GetStaticPaths = () => { const { internationalization } = getConfiguration(); const { locales } = internationalization; const paths = locales.map((locale) => ({ params: { locale }, })); return { paths, fallback: false };};export const getStaticProps: GetStaticProps = ({ params }) => { const locale = params?.locale as string; return { props: { locale, }, };};export default HomePage;
getStaticPaths e getStaticProps assicurano che la tua applicazione precompili le pagine necessarie per tutte le localizzazioni nel Page Router di Next.js. Questo approccio riduce il calcolo a runtime e porta a un'esperienza utente migliorata. Per maggiori dettagli, consulta la documentazione di Next.js su getStaticPaths e getStaticProps.
Passo 6: Dichiarare il Tuo Contenuto
Crea e gestisci le tue dichiarazioni di contenuto per memorizzare le traduzioni.
import { t, type Dictionary } from "intlayer";const homeContent = { key: "home", content: { title: t({ en: "Welcome to My Website", fr: "Bienvenue sur mon site Web", es: "Bienvenido a mi sitio web", }), description: t({ en: "Inizia modificando questa pagina.", fr: "Commencez par éditer cette page.", es: "Comience por editar esta página.", }), },} satisfies Dictionary;export default homeContent;
Per maggiori informazioni sulla dichiarazione dei contenuti, consulta la guida alla dichiarazione dei contenuti.
Passo 7: Utilizza i Contenuti nel Tuo Codice
Accedi ai tuoi dizionari di contenuti in tutta l'applicazione per visualizzare contenuti tradotti.
import type { FC } from "react";import { useIntlayer } from "next-intlayer";import { ComponentExample } from "@components/ComponentExample";const HomePage: FC = () => { const content = useIntlayer("home"); return ( <div> <h1>{content.title}</h1> <p>{content.description}</p> <ComponentExample /> {/* Componenti aggiuntivi */} </div> );};// ... Resto del codice, inclusi getStaticPaths e getStaticPropsexport default HomePage;
import type { FC } from "react";import { useIntlayer } from "next-intlayer";export const ComponentExample: FC = () => { const content = useIntlayer("component-example"); // Assicurati di avere una dichiarazione di contenuto corrispondente return ( <div> <h2>{content.title}</h2> <p>{content.content}</p> </div> );};
Quando usi traduzioni in attributi di tipo string (ad esempio, alt, title, href, aria-label), chiama
il valore della funzione come segue:
jsx<img src={content.image.src.value} alt={content.image.value} />
Per saperne di più sull'hook useIntlayer, consulta la documentazione.
(Opzionale) Passo 8: Internazionalizzazione dei tuoi metadata
Nel caso tu voglia internazionalizzare i tuoi metadata, come il titolo della tua pagina, puoi utilizzare la funzione getStaticProps fornita dal Page Router di Next.js. All'interno, puoi recuperare il contenuto dalla funzione getIntlayer per tradurre i tuoi metadata.
import { type Dictionary, t } from "intlayer";import { type Metadata } from "next";const metadataContent = { key: "page-metadata", content: { title: t({ en: "Create Next App", fr: "Créer une application Next.js", es: "Crear una aplicación Next.js", }), description: t({ en: "Generated by create next app", fr: "Généré par create next app", es: "Generado por create next app", }), },} satisfies Dictionary<Metadata>;export default metadataContent;
import { GetStaticPaths, GetStaticProps } from "next";import { getIntlayer, getMultilingualUrls } from "intlayer";import { useIntlayer } from "next-intlayer";import Head from "next/head";import type { FC } from "react";interface HomePageProps { locale: string; metadata: { title: string; description: string; }; multilingualUrls: Record<string, string>;}const HomePage: FC<HomePageProps> = ({ metadata, multilingualUrls, locale,}) => { const content = useIntlayer("page"); return ( <div> <Head> <title>{metadata.title}</title> <meta name="description" content={metadata.description} /> {/* Genera tag hreflang per SEO */} {Object.entries(multilingualUrls).map(([lang, url]) => ( <link key={lang} rel="alternate" hrefLang={lang} href={url} /> ))} <link rel="canonical" href={multilingualUrls[locale]} /> </Head> {/* Contenuto della pagina */} <main>{/* Il contenuto della tua pagina qui */}</main> </div> );};export const getStaticProps: GetStaticProps<HomePageProps> = async ({ params,}) => { const locale = params?.locale as string; const metadata = getIntlayer("page-metadata", locale); /** * Genera un oggetto contenente tutti gli URL per ogni lingua. * * Esempio: * ```ts * getMultilingualUrls('/about'); * * // Restituisce * // { * // en: '/about', * // fr: '/fr/about', * // es: '/es/about', * // } * ``` */ const multilingualUrls = getMultilingualUrls("/"); return { props: { locale, metadata, multilingualUrls, }, };};export default HomePage;// ... Resto del codice incluso getStaticPaths
Nota che la funzione getIntlayer importata da next-intlayer restituisce il tuo contenuto racchiuso in un IntlayerNode, permettendo l'integrazione con l'editor visuale. Al contrario, la funzione getIntlayer importata da intlayer restituisce il tuo contenuto direttamente senza proprietà aggiuntive.
In alternativa, puoi utilizzare la funzione getTranslation per dichiarare i tuoi metadata. Tuttavia, si consiglia di utilizzare i file di dichiarazione dei contenuti per automatizzare la traduzione dei tuoi metadata ed esternalizzare il contenuto a un certo punto.
import { GetStaticPaths, GetStaticProps } from "next";import { type IConfigLocales, getTranslation, getMultilingualUrls,} from "intlayer";import { useIntlayer } from "next-intlayer";import Head from "next/head";import type { FC } from "react";interface HomePageProps { locale: string; metadata: { title: string; description: string; }; multilingualUrls: Record<string, string>;}const HomePage: FC<HomePageProps> = ({ metadata, multilingualUrls, locale }) => { const content = useIntlayer("page"); return ( <div> <Head> <title>{metadata.title}</title> <meta name="description" content={metadata.description} /> {/* Genera tag hreflang per SEO */} {Object.entries(multilingualUrls).map(([lang, url]) => ( <link key={lang} rel="alternate" hrefLang={lang} href={url} /> ))} <link rel="canonical" href={multilingualUrls[locale]} /> </Head> {/* Contenuto della pagina */} <main> {/* Il contenuto della tua pagina qui */} </main> </div> );};export const getStaticProps: GetStaticProps<HomePageProps> = async ({ params}) => { const locale = params?.locale as string; const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale); const metadata = { title: t<string>({ en: "My title", fr: "Mon titre", es: "Mi título", }), description: t({ en: "My description", fr: "Ma description", es: "Mi descripción", }), }; const multilingualUrls = getMultilingualUrls("/"); return { props: { locale, metadata, multilingualUrls, }, };};export default HomePage;// ... Resto del codice incluso getStaticPaths
Scopri di più sull'ottimizzazione dei metadata nella documentazione ufficiale di Next.js.
(Opzionale) Passo 9: Cambiare la lingua del tuo contenuto
Per cambiare la lingua del tuo contenuto in Next.js, il modo consigliato è utilizzare il componente Link per reindirizzare gli utenti alla pagina localizzata appropriata. Il componente Link abilita il prefetching della pagina, il che aiuta a evitare un ricaricamento completo della pagina.
import { Locales, getHTMLTextDir, getLocaleName, getLocalizedUrl,} from "intlayer";import { useLocalePageRouter } from "next-intlayer";import { type FC } from "react";import Link from "next/link";const LocaleSwitcher: FC = () => { const { locale, pathWithoutLocale, availableLocales } = useLocalePageRouter(); const { setLocaleCookie } = useLocaleCookie(); return ( <div> <button popoverTarget="localePopover">{getLocaleName(locale)}</button> <div id="localePopover" popover="auto"> {availableLocales.map((localeItem) => ( <Link href={getLocalizedUrl(pathWithoutLocale, localeItem)} hrefLang={localeItem} key={localeItem} aria-current={locale === localeItem ? "page" : undefined} onClick={() => setLocaleCookie(localeItem)} > <span> {/* Locale - es. FR */} {localeItem} </span> <span> {/* Lingua nella sua stessa Locale - es. Français */} {getLocaleName(localeItem, locale)} </span> <span dir={getHTMLTextDir(localeItem)} lang={localeItem}> {/* Lingua nella localizzazione corrente - es. Francés con la localizzazione corrente impostata su Locales.SPANISH */} {getLocaleName(localeItem)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* Lingua in inglese - es. French */} {getLocaleName(localeItem, Locales.ENGLISH)} </span> </Link> ))} </div> </div> );};
Un modo alternativo è utilizzare la funzione setLocale fornita dall'hook useLocale. Questa funzione non permetterà il prefetching della pagina e ricaricherà la pagina.
In questo caso, senza il reindirizzamento usando router.push, solo il codice lato server cambierà la localizzazione del contenuto.
"use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Resto del codiceconst router = useRouter();const { setLocale } = useLocale({ onLocaleChange: (locale) => { router.push(getLocalizedUrl(pathWithoutLocale, locale)); },});return ( <button onClick={() => setLocale(Locales.FRENCH)}>Cambia in francese</button>);
L'API useLocalePageRouter è la stessa di useLocale. Per saperne di più sull'hook useLocale, consulta la documentazione.
Riferimenti alla documentazione:
(Opzionale) Passo 10: Creare un Componente Link Localizzato
Per garantire che la navigazione della tua applicazione rispetti la locale corrente, puoi creare un componente Link personalizzato. Questo componente aggiunge automaticamente il prefisso della lingua corrente agli URL interni. Ad esempio, quando un utente francofono clicca su un link alla pagina "About", viene reindirizzato a /fr/about invece che a /about.
Questo comportamento è utile per diversi motivi:
- SEO e esperienza utente: Gli URL localizzati aiutano i motori di ricerca a indicizzare correttamente le pagine specifiche per lingua e forniscono agli utenti contenuti nella loro lingua preferita.
- Coerenza: Utilizzando un link localizzato in tutta l'applicazione, si garantisce che la navigazione rimanga all'interno della locale corrente, evitando cambiamenti di lingua imprevisti.
- Manutenibilità: Centralizzare la logica di localizzazione in un unico componente semplifica la gestione degli URL, rendendo il codice più facile da mantenere ed estendere man mano che l'applicazione cresce.
Di seguito è riportata l'implementazione di un componente Link localizzato in TypeScript:
"use client";import { getLocalizedUrl } from "intlayer";import NextLink, { type LinkProps as NextLinkProps } from "next/link";import { useLocale } from "next-intlayer";import { forwardRef, PropsWithChildren, type ForwardedRef } from "react";/** * Funzione di utilità per verificare se un URL è esterno. * Se l'URL inizia con http:// o https://, è considerato esterno. */export const checkIsExternalLink = (href?: string): boolean => /^https?:\/\//.test(href ?? "");/** * Un componente Link personalizzato che adatta l'attributo href in base alla locale corrente. * Per i link interni, utilizza `getLocalizedUrl` per anteporre la locale all'URL (es. /fr/about). * Questo garantisce che la navigazione rimanga all'interno dello stesso contesto locale. */export const Link = forwardRef< HTMLAnchorElement, PropsWithChildren<NextLinkProps>>(({ href, children, ...props }, ref: ForwardedRef<HTMLAnchorElement>) => { const { locale } = useLocale(); const isExternalLink = checkIsExternalLink(href.toString()); // Se il link è interno e viene fornito un href valido, ottieni l'URL localizzato. const hrefI18n: NextLinkProps["href"] = href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href; return ( <NextLink href={hrefI18n} ref={ref} {...props}> {children} </NextLink> );});Link.displayName = "Link";
Come Funziona
Rilevamento dei Link Esterni:
La funzione di supporto checkIsExternalLink determina se un URL è esterno. I link esterni vengono lasciati invariati perché non necessitano di localizzazione.Recupero della Locale Corrente:
Il hook useLocale fornisce la locale corrente (ad esempio, fr per il francese).Localizzazione dell'URL:
Per i link interni (cioè non esterni), getLocalizedUrl viene utilizzato per aggiungere automaticamente il prefisso della locale corrente all'URL. Ciò significa che se l'utente è in francese, passando /about come href verrà trasformato in /fr/about.Restituzione del Link:
Il componente restituisce un elemento <a> con l'URL localizzato, garantendo che la navigazione sia coerente con la locale.
Integrando questo componente Link in tutta la tua applicazione, mantieni un'esperienza utente coerente e consapevole della lingua, beneficiando anche di un miglior SEO e usabilità.
(Opzionale) Passo 11: Ottimizza la dimensione del bundle
Quando si utilizza next-intlayer, i dizionari sono inclusi nel bundle per ogni pagina per impostazione predefinita. Per ottimizzare la dimensione del bundle, Intlayer fornisce un plugin SWC opzionale che sostituisce in modo intelligente le chiamate a useIntlayer utilizzando macro. Questo garantisce che i dizionari siano inclusi solo nei bundle delle pagine che li utilizzano effettivamente.
Per abilitare questa ottimizzazione, installa il pacchetto @intlayer/swc. Una volta installato, next-intlayer rileverà automaticamente e utilizzerà il plugin:
npm install @intlayer/swc --save-dev
Nota: Questa ottimizzazione è disponibile solo per Next.js 13 e versioni successive.
Nota: Questo pacchetto non è installato di default perché i plugin SWC sono ancora sperimentali su Next.js. Potrebbe cambiare in futuro.
Configurare TypeScript
Intlayer utilizza l'augmentation dei moduli per sfruttare i vantaggi di TypeScript e rendere il tuo codice più robusto.
Assicurati che la tua configurazione di TypeScript includa i tipi generati automaticamente.
{ // ... Le tue configurazioni TypeScript esistenti "include": [ // ... Le tue configurazioni TypeScript esistenti ".intlayer/**/*.ts", // Includi i tipi generati automaticamente ],}
Configurazione Git
Per mantenere il tuo repository pulito ed evitare di commettere file generati, è consigliato ignorare i file creati da Intlayer.
Aggiungi le seguenti righe al tuo file .gitignore:
# Ignora i file generati da Intlayer.intlayer
Estensione VS Code
Per migliorare la tua esperienza di sviluppo con Intlayer, puoi installare l'Estensione ufficiale Intlayer per VS Code.
Installa dal Marketplace di VS Code
Questa estensione offre:
- Completamento automatico per le chiavi di traduzione.
- Rilevamento errori in tempo reale per traduzioni mancanti.
- Anteprime inline dei contenuti tradotti.
- Azioni rapide per creare e aggiornare facilmente le traduzioni.
Per maggiori dettagli su come utilizzare l'estensione, consulta la documentazione dell'estensione Intlayer per VS Code.
Risorse Aggiuntive
- Documentazione Intlayer: Repository GitHub
- Guida al Dizionario: Dizionario
- Documentazione di Configurazione: Guida alla Configurazione
Seguendo questa guida, puoi integrare efficacemente Intlayer nella tua applicazione Next.js utilizzando il Page Router, abilitando un supporto per l'internazionalizzazione robusto e scalabile per i tuoi progetti web.
Vai Oltre
Per andare oltre, puoi implementare l'editor visuale o esternalizzare i tuoi contenuti utilizzando il CMS.
Cronologia della documentazione
- 5.5.10 - 2025-06-29: Inizio cronologia
Se hai un’idea per migliorare questa documentazione, non esitare a contribuire inviando una pull request su GitHub.
Collegamento GitHub alla documentazione