Nextjs+next-intl flerspråkiga internationalisering bästa praxis (APP-router)
Nextjs har två routrar: APP-router och Page-router.
För en tid sedan, under Page-routern, internationaliserades nextjs och sammanfattades:
Men Page-routern kommer att vara routern som gradvis fasas ut av Nextjs. Därför har Nextjs nyligen internationaliserats baserat på APP-router.
1. Val av Nextjs internationaliseringslösning
1. i18next + react-i18next + i18next-resources-to-backend + next-i18n-router
Det verkar som att de flesta använder detta. Jag provade det och det var ganska komplicerat. Jag lyckades inte ännu, så jag gav upp.
2. nästa-i18n-router react-intl
Det såg ganska komplicerat ut, men på grund av skuggan av 1 gav jag upp.
3. nästa-intl
next-intl är en komplett internationaliseringslösning för nextjs och kräver inga andra programvarupaket. Och konfigurationen är relativt enkel. Ännu viktigare, jag konfigurerade det framgångsrikt och stötte på inga oförklarliga problem.
Så det här är det.
2. Katalogstruktur
|app ..[locale] ...layout.js ...page.js |komponenter ..LangSwitcher.js |public ..locales ...en ....common.json ...es .... common.json |i18n.js |navigation.js |middleware.js |next.config.js
3. Internationell routing
1. navigation.js
Detta är en konfigurationsfil, och objekten som konfigurerats i den här filen kommer att anropas i vissa andra filer.
importera { createSharedPathnamesNavigation } från 'next-intl/navigation'; export const locales = ['en', 'de', 'es', 'ja','ko','it','pt']; = 'efter behov'; export const defaultLocale= "en" export const localeItems= [ { namn: "engelska", kod: "en", iso: "en-US", dir: "ltr" }, { namn : "español", kod: "es", iso: "es-ES", dir: "ltr" }, { namn: "中文",kod: "zh_cn", iso: "zh-CN", dir: " ltr" }, { namn: "Deutsch", kod: "de", iso: "de-DE", dir: "ltr" }, { namn: "Italiano", kod: "it", iso: "it- IT", dir: "ltr" }, { namn: "日本语",kod: "ja", iso: "ja-JP", dir: "ltr" }, {namn: "한국인",kod: "ko ", iso: "ko-KR", dir: "ltr" }, { namn: "Português", kod: "pt", iso: "pt-PT", dir: "ltr" }, ] export const { Länk , redirect, usePathname, useRouter } = createSharedPathnamesNavigation({ locales, localePrefix });
2. [locale] katalog
Alla sidfiler i appkatalogen placeras i [locale]-katalogen.
3. Middleware: middleware.js
illustrera:
Implementera följande URL-stil
Webbadress för standardspråk:
Hemsidan är: www.xxx.com
Den inre sidan är: www.xxx.com/about
Webbadresser på andra språk: (ta spanska som exempel)
Hemsidan är: www.xxx.com/es
Den inre sidan är: www.xxx.com/es/about
Dessutom, om standardspråket anges i URL:en, till exempel, standardspråket är engelska, anger användaren URL:en: www.xxx.com/en
Sedan går den automatiskt till www.xxx.com
Koda:
import createMiddleware från "next-intl/middleware" import { defaultLocale, localePrefix, locales } från '@/navigation' export default createMiddleware ({ locales, localePrefix , defaultLocale, localeDetection: false, }); / Hoppa över alla sökvägar som inte bör internationaliseras // Detta hoppar över mapparna "api", "_next" och alla filer // med en filändelse (t.ex. favicon.ico) matcher: ["/(?!api|_next|. .*\\..*).*)"], };
4. Ladda översättningsfiler
1. Översätt filer
illustrera
Mina översättningsfiler placeras i den "offentliga" katalogen, men i själva verket kan översättningsfilerna också placeras i andra kataloger, så länge som motsvarande sökväg är konfigurerad i filen i18n.js.
Översättningsfilen är en json-fil, och json-filen kan vara i ett kapslat format eller inte. De två kommer i slutändan att refereras något annorlunda.
Kod (ej kapslad)
{ "aaa": "hej", }
Kod (kapslad)
{ "bbb":{ "aaa":"hej", } }
2. i18n.js-fil
illustrera:
Den här filen används för att importera översättningsfiler. Nyckeln är att konfigurera sökvägen till översättningsfilen, som måste överensstämma med sökvägen där din översättningsfil finns.
${locale} i sökvägen indikerar språket.
koda
importera { getRequestConfig } från "next-intl/server"; // Skapa den här konfigurationen en gång per begäran och // gör den tillgänglig för alla serverkomponenter för exportstandard getRequestConfig(async ({ locale }) => ({ // Ladda översättningar. för det aktiva språkmeddelandet: (avvaktar import(`./public/locales/${locale}/common.json`)).default, }));
3. Konfiguration av next.config.js
/** @typ {import('next').NextConfig} */ const nextConfig = {} const withNextIntl= require("next-intl/plugin")("./i18n.js"); =withNextIntl (nextConfig)
5. Implementera översättning
Kod i layout.js:
importera "./globals.css"; importera { NextIntlClientProvider, useMessages } från 'next-intl'; importera { locales } från '@/navigation'; importera sidfot från '@/components' /Footer' export standardfunktion RootLayout({ barn, params: { locale } }) { if (!locales.includes(locale)) { notFound( } const messages = useMessages();
<html lang="{locale}">
<nextintlclientprovider locale="{locale}" messages="{messages}">
<body><header />{barn}<footer /></body>
</nextintlclientprovider>
</html>
);
}
Kod i page.js:
Parametern locale representerar det aktuella språket.
Om översättningsfilen inte är kapslad, då const t = useTranslations();
Om översättningsfilen är kapslad, använd något som: const t = useTranslations("bbb" baserat på filstrukturen och faktiska behov.
importera { useTranslations } från 'next-intl' import { Link } från '@/navigation' export standardfunktion Home({ params: { locale } }) { const t = useTranslations();<>
<link href="{"/"}"><h1>{t("aaa")}</h1></Link>
</>)
6. Språkväxlare
1. Effekt
Dra ned för att välja ett språk och den aktuella sidan växlar till sidan på det valda språket.
2. Kod
"use client";
import { useLocale } from "next-intl";
import { localeItems, useRouter, usePathname, defaultLocale } from '@/navigation';
export default function LangSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
console.log(locale)
const handleChange = (e) => {
router.push(pathname, { locale: e.target.value });
};
return (
<div>
<select
value={locale}
onChange={handleChange}
className="h-8 m-2 p-1 rounded border-current"
>
<option value={locale} > {GetLangData(locale).name}</option>
{localeItems.map((item) => {
if (item.code === locale) return null
return (<option key={item.code} value={item.code}>
{item.name}
</option>)
})}
</select>
</div>
);
}
export function GetLangData(defaultLocale) {
var res = {}
{
localeItems.map(locale => {
if (locale.code === defaultLocale) {
console.log(locale)
res = locale
}
})
}
return res
}
7. SEO och sökmotorvänlig
1. Metadata
Nextjs APP-router genererar sidans titel och metadata. Jag försökte tre metoder:
Det första sättet: använd det direkt i layout.js: expert const metadata={}
Det andra sättet: använd dynamiskt genererad metadata i page.js
Som referens:Optimera: Metadata |. Next.js (nextjs.org)
På dessa två sätt misslyckades jag med flerspråkig titel och metadata. Slutligen användes den tredje metoden, som också är den enklaste och mest raka metoden.
Det tredje sättet: skriv titeltaggen och metataggen direkt i page.js.
Därför ändrades koden för page.js till detta:
importera { useTranslations } från 'next-intl' import { Link } från '@/navigation' export standardfunktion Home({ params: { locale } }) { const t = useTranslations();<>
<title>{t("webbplatsnamn")}</title>
<meta name="keyword" content="{t("site-name")}"></meta>
<meta name="description" content="{t("webbplatsbeskrivning")}"></meta>
<meta property="og:type" content="website"></meta>
<meta property="og:title" content="{t("webbplatsnamn")}"></meta>
<meta property="og:description" content="{t("webbplatsbeskrivning")}"></meta>
<meta property="og:site_name" content="{t("webbplatsnamn")}"></meta>
<meta property="og:image" content="/images/xxx.png"></meta>
<meta property="og:image:width" content="512"></meta>
<meta property="og:image:height" content="512"></meta>
<meta property="og:image:alt" content=""></meta>
<link href="{"/"}"><h1>{t("aaa")}</h1></Link>
</>)
2. Flerspråkig navigering: Gör det lättare för sökmotorer att upptäcka flerspråkiga webbadresser
illustrera
Språkväxlaren är frontend-renderad, så jag lade till back-end-renderad flerspråkig navigering längst ner på sidan, som är komponenten Footer.js. Om du klickar på motsvarande språk kommer du till hemsidans hemsida på detta språk.
Footer.js-koden är följande:
import Link from 'next/link'
import { localeItems,defaultLocale } from '@/navigation';
export default function Footer(){
return (<>
<div className="divider"></div>
<footer className="footer footer-center p-10 bg-base-200 text-base-content rounded">
<nav className="flex flex-wrap gap-4">
{localeItems.map(locale => {
if (locale.code === defaultLocale) return(<Link className="link link-hover" href="/" key={locale.code}>{locale.name}</Link>)
const thehref="/"+locale.code
return (<Link className="link link-hover" href={thehref} key={locale.code}> {locale.name}</Link>)
})}
</nav>
<aside className='p-6 text-center'>
<p>Copyright © 2024 - All right reserved by xxx.com</p>
</aside>
</footer>
</>
)
}
8. Sammanfattning
Internationell routing, struktur och introduktion av översättningsfiler och implementering av översättning. Oavsett vilken typ av internationaliseringsplan kommer dessa tre aspekter att vara inblandade. Även om det inte är besvärligt, är next-intl i allmänhet relativt enkelt.
9. Referens
En djupdykning i Next.js App Router Localization med next-intl
En komplett guide för att ställa in next-intl med App Router