Introduzione all'Internazionalizzazione (i18n) con Intlayer e Next.js utilizzando Page Router
Cos'è Intlayer?
Intlayer è una libreria innovativa e open-source per l'internazionalizzazione (i18n) progettata per semplificare il supporto multilingue nelle applicazioni web moderne. Intlayer si integra perfettamente con l'ultimo framework Next.js, incluso il tradizionale Page Router.
Con Intlayer, puoi:
- Gestire facilmente le traduzioni utilizzando dizionari dichiarativi a livello di componente.
- Localizzare dinamicamente metadati, percorsi e contenuti.
- Garantire il supporto TypeScript con tipi autogenerati, migliorando l'autocompletamento e il rilevamento degli errori.
- Beneficiare di funzionalità avanzate, come il rilevamento dinamico della lingua e il cambio di lingua.
Intlayer è compatibile con Next.js 12, 13, 14 e 15. Se stai utilizzando Next.js App Router, consulta la guida per App Router. Per Next.js 15, segui questa guida.
Guida Passo-Passo per Configurare Intlayer in un'Applicazione Next.js Utilizzando Page Router
Passo 1: Installa le Dipendenze
Installa i pacchetti necessari utilizzando il tuo gestore di pacchetti preferito:
npm install intlayer next-intlayer
intlayer
Il pacchetto principale che fornisce strumenti di internazionalizzazione per la gestione delle configurazioni, traduzioni, dichiarazione dei contenuti, transpilation e comandi CLI.
next-intlayer
Il pacchetto che integra Intlayer con Next.js. Fornisce provider di contesto e hook per l'internazionalizzazione di Next.js. Inoltre, include il plugin Next.js per integrare Intlayer con Webpack o Turbopack, oltre a middleware per rilevare la lingua preferita dell'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 lingue ], defaultLocale: Locales.ENGLISH, },};export default config;
Tramite questo file di configurazione, puoi configurare URL localizzati, reindirizzamenti middleware, nomi dei cookie, la posizione e l'estensione delle 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: Integra 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 withIntlayer() di Next.js viene utilizzato per integrare Intlayer con Next.js. Garantisce la costruzione dei file di dichiarazione dei contenuti e li monitora in modalità di sviluppo. Definisce le variabili d'ambiente di Intlayer all'interno degli ambienti Webpack o Turbopack. Inoltre, fornisce alias per ottimizzare le prestazioni e garantisce la compatibilità con i componenti server.
Passo 4: Configura il Middleware per il Rilevamento della Lingua
Configura il middleware per rilevare e gestire automaticamente la lingua preferita dell'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 ai percorsi della tua applicazione. Per maggiori dettagli, consulta la documentazione di Next.js sulla configurazione del matcher.
Passo 5: Definisci Percorsi Dinamici per le Lingue
Implementa il routing dinamico per servire contenuti localizzati in base alla lingua dell'utente.
Crea Pagine Specifiche per 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 tuo _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;
Configura getStaticPaths e getStaticProps:
Nel tuo [locale]/index.tsx, definisci i percorsi e le proprietà per gestire le diverse lingue.
src/pages/[locale]/index.tsximport type { FC } from "react";import type { GetStaticPaths, GetStaticProps } from "next";import { type Locales, getConfiguration } from "intlayer";
const HomePage: FC = () =>
getStaticPaths e getStaticProps assicurano che la tua applicazione pre-costruisca le pagine necessarie per tutte le localizzazioni nel Page Router di Next.js. Questo approccio riduce il calcolo a runtime e migliora l'esperienza utente. Per ulteriori dettagli, consulta la documentazione di Next.js su getStaticPaths e getStaticProps.
Step 6: Dichiarare il tuo contenuto
Crea e gestisci le dichiarazioni di contenuto per memorizzare le traduzioni.
import { t, type Dictionary } from "intlayer";const homeContent = { key: "home", content: { title: t({ it: "Benvenuto nel mio sito web", en: "Welcome to My Website", fr: "Bienvenue sur mon site Web", es: "Bienvenido a mi sitio web", }), description: t({ it: "Inizia modificando questa pagina.", en: "Get started by editing this page.", fr: "Commencez par éditer cette page.", es: "Comience por editar esta página.", }), },} satisfies Dictionary;export default homeContent;
Per ulteriori informazioni sulla dichiarazione del contenuto, consulta la guida alla dichiarazione del contenuto.
Step 7: Utilizzare il contenuto nel tuo codice
Accedi ai tuoi dizionari di contenuto in tutta l'applicazione per visualizzare il contenuto tradotto.
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 si utilizzano traduzioni in attributi string (ad esempio, alt, title, href, aria-label), chiamare il valore della funzione come segue:
jsx<img src={content.image.src.value} alt={content.image.value} />
Per saperne di più sul hook useIntlayer, fare riferimento alla documentazione.
(Opzionale) Passo 8: Internazionalizzare i Metadati
Per internazionalizzare metadati come titoli di pagina e descrizioni, utilizzare la funzione getStaticProps in combinazione con la funzione getTranslation di Intlayer.
import { GetStaticPaths, GetStaticProps } from "next";import { type IConfigLocales, getTranslation, Locales } from "intlayer";import { useIntlayer } from "next-intlayer";interface HomePageProps { locale: string; metadata: Metadata;}const HomePage = ({ metadata }: HomePageProps) => { // I metadati possono essere utilizzati nell'head o in altri componenti secondo necessità return ( <div> <Head> <title>{metadata.title}</title> <meta name="description" content={metadata.description} /> </Head> {/* Contenuto aggiuntivo */} </div> );};export const getStaticProps: GetStaticProps = async ({ params }) => { const locale = params?.locale as string; const t = <T,>(content: IConfigLocales<T>) => getTranslation(content, locale); const metadata = { title: t({ it: "Il Mio Sito Web", en: "My Website", fr: "Mon Site Web", es: "Mi Sitio Web", }), description: t({ it: "Benvenuto sul mio sito web.", en: "Welcome to my website.", fr: "Bienvenue sur mon site Web.", es: "Bienvenido a mi sitio web.", }), }; return { props: { locale, metadata, }, };};export default HomePage;// ... Resto del codice incluso getStaticPaths
(Opzionale) Passo 9: Cambiare la Lingua del Contenuto
Per consentire agli utenti di cambiare lingua dinamicamente, utilizzare la funzione setLocale fornita dall'hook useLocale.
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, setLocale } = useLocalePageRouter(); 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={(e) => { e.preventDefault(); setLocale(localeItem); }} > <span> {/* Locale - ad esempio IT */} {localeItem} </span> <span> {/* Lingua nel proprio Locale - ad esempio Italiano */} {getLocaleName(localeItem, locale)} </span> <span dir={getHTMLTextDir(localeItem)} lang={localeItem}> {/* Lingua nel Locale corrente - ad esempio Italiano con locale corrente impostato su Locales.ITALIAN */} {getLocaleName(localeItem)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* Lingua in Inglese - ad esempio Italian */} {getLocaleName(localeItem, Locales.ENGLISH)} </span> </Link> ))} </div> </div> );};
L'API useLocalePageRouter è la stessa di useLocale. Per saperne di più sul 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 alle URL interne con la lingua corrente. Ad esempio, quando un utente francofono clicca su un link alla pagina "Chi siamo", viene reindirizzato a /it/about invece di /about.
Questo comportamento è utile per diversi motivi:
- SEO e Esperienza Utente: Le URL localizzate 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, garantisci che la navigazione rimanga nella locale corrente, evitando cambiamenti di lingua inaspettati.
- Manutenibilità: Centralizzare la logica di localizzazione in un unico componente semplifica la gestione delle URL, rendendo il tuo 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 aggiungere il prefisso dell'URL con la locale (ad esempio, /it/about). * Questo garantisce che la navigazione rimanga nel contesto della locale corrente. */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 helper checkIsExternalLink determina se un URL è esterno. I link esterni rimangono invariati poiché non necessitano di localizzazione.Recupero della Locale Corrente:
L'hook useLocale fornisce la locale corrente (ad esempio, it per Italiano).Localizzazione dell'URL:
Per i link interni (cioè non esterni), getLocalizedUrl viene utilizzato per aggiungere automaticamente il prefisso dell'URL con la locale corrente. Questo significa che se il tuo utente è in Italiano, passando /about come href verrà trasformato in /it/about.Restituzione del Link:
Il componente restituisce un elemento <a> con l'URL localizzato, garantendo che la navigazione sia coerente con la locale.
Configurare TypeScript
Intlayer utilizza l'estensione dei moduli per sfruttare i vantaggi di TypeScript e rendere il tuo codice più robusto.
Assicurati che la configurazione di TypeScript includa i tipi autogenerati.
{ // ... Le tue configurazioni TypeScript esistenti "include": [ // ... Le tue configurazioni TypeScript esistenti ".intlayer/**/*.ts", // Includi i tipi autogenerati ],}
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
Risorse Aggiuntive
- Documentazione Intlayer: Repository GitHub
- Guida al Dizionario: Dizionario
- Documentazione Configurazione: Guida alla Configurazione
Seguendo questa guida, puoi integrare efficacemente Intlayer nella tua applicazione Next.js utilizzando il Page Router, abilitando un supporto di internazionalizzazione robusto e scalabile per i tuoi progetti web.
Approfondisci
Per approfondire, puoi implementare l'editor visivo o esternalizzare i tuoi contenuti utilizzando il CMS.
Se hai un’idea per migliorare questa documentazione, non esitare a contribuire inviando una pull request su GitHub.
Collegamento GitHub alla documentazione