Najlepsza praktyka w zakresie internacjonalizacji wielu języków Nextjs+nex-intl (router aplikacji)
Nextjs ma dwa routery: router APP i router Page.
Jakiś czas temu pod routerem Page, nextjs został umiędzynarodowiony i podsumowany:
Jednak router Page będzie routerem stopniowo wycofywanym przez Nextjs. Dlatego ostatnio Nextjs został umiędzynarodowiony w oparciu o router APP.
1. Wybór międzynarodowych rozwiązań Nextjs
1. i18next + reakcja-i18next + i18next-resources-to-backend + router next-i18n
Wygląda na to, że większość ludzi tego używa. Próbowałem tego i było to dość skomplikowane, ale jeszcze mi się to nie udało, więc się poddałem.
2. następny router i18n reaguje-intl
Wyglądało to dość skomplikowanie, ale ze względu na cień 1 poddałem się.
3. następny-intl
next-intl to kompletne rozwiązanie do internacjonalizacji dla nextjs i nie wymaga innych pakietów oprogramowania. A konfiguracja jest stosunkowo prosta. Co ważniejsze, skonfigurowałem go pomyślnie i nie napotkałem żadnych niewytłumaczalnych problemów.
Więc to jest to.
2. Struktura katalogów
|app ..[locale] ...layout.js ...page.js |komponenty ..LangSwitcher.js |public ..locales ...en ....common.json ...es .... common.json |i18n.js |navigation.js |middleware.js |next.config.js
3. Trasy międzynarodowe
1. nawigacja.js
To jest plik konfiguracyjny i elementy skonfigurowane w tym pliku będą wywoływane w innych plikach.
import { createSharedPathnamesNavigation } z 'next-intl/navigation' eksport const locales = ['en', 'de', 'es', 'ja','ko','it','pt']; eksport const localePrefix = 'w razie potrzeby'; eksport const defaultLocale= "en"; eksport const localeItems= [ { nazwa: "angielski", kod: "en", iso: "en-US", katalog: "ltr" }, { nazwa : „español”, kod: „es”, iso: „es-ES”, reż: „ltr” }, { nazwa: „中文”, kod: „zh_cn”, iso: „zh-CN”, reż: „ ltr" }, { nazwa: "Deutsch", kod: "de", iso: "de-DE", reż: "ltr" }, { nazwa: "Italiano", kod: "it", iso: "it- IT”, reż: „ltr” }, { nazwa: „日本语”, kod: „ja”, iso: „ja-JP”, reż: „ltr” }, { nazwa: „한국인”, kod: „ko ", iso: "ko-KR", reż: "ltr" }, { nazwa: "Português", kod: "pt", iso: "pt-PT", reż: "ltr" }, ] eksport const { Link , redirect, usePathname, useRouter } = createSharedPathnamesNavigation({ locale, localePrefix });
2. Katalog [locale].
Wszystkie pliki stron w katalogu aplikacji są umieszczane w katalogu [locale].
3. Oprogramowanie pośrednie: oprogramowanie pośrednie.js
zilustrować:
Zaimplementuj następujący styl adresu URL
Domyślny adres URL języka:
Strona główna to: www.xxx.com
Wewnętrzna strona to: www.xxx.com/about
Adresy URL w innych językach: (na przykładzie hiszpańskiego)
Strona główna to: www.xxx.com/es
Wewnętrzna strona to: www.xxx.com/es/about
Dodatkowo, jeśli w adresie URL wpisany jest domyślny język, np. domyślnym językiem jest angielski, użytkownik wpisuje adres URL: www.xxx.com/pl
Następnie automatycznie przejdzie do witryny www.xxx.com
Kod:
importuj createMiddleware z "next-intl/middleware"; importuj { defaultLocale, localePrefix, locales } z '@/navigation'; eksportuj domyślne createMiddleware({ locale, localePrefix, defaultLocale, localeDetection: false, }); / Pomiń wszystkie ścieżki, które nie powinny być umiędzynarodowione. // Spowoduje to pominięcie folderów „api”, „_next” i wszystkich plików // z rozszerzeniem (np. favicon.ico) matcher: ["/((?!api|_next| .*\\..*).*)"], };
4. Załaduj pliki tłumaczeń
1. Przetłumacz pliki
zilustrować
Moje pliki tłumaczeń znajdują się w katalogu „public”, ale tak naprawdę pliki tłumaczeń można umieścić także w innych katalogach, o ile odpowiednia ścieżka jest skonfigurowana w pliku i18n.js.
Plik tłumaczenia jest plikiem json i plik json może mieć format zagnieżdżony lub nie. Ostatecznie te dwa określenia będą nieco inaczej określane.
Kod (niezagnieżdżony)
{ "aaa": "cześć", }
Kod (zagnieżdżony)
{ "bbb":{ "aaa":"cześć", } }
2. plik i18n.js
zilustrować:
Plik ten służy do importowania plików tłumaczeń. Kluczem jest skonfigurowanie ścieżki pliku tłumaczenia, która musi być zgodna ze ścieżką, w której znajduje się plik tłumaczenia.
${locale} w ścieżce wskazuje język.
kod
import { getRequestConfig } z "next-intl/server"; // Utwórz tę konfigurację raz na żądanie i // udostępnij ją wszystkim komponentom serwera eksport domyślny getRequestConfig(async ({ locale }) => ({ // Załaduj tłumaczenia dla aktywnych komunikatów locale: (await import(`./public/locales/${locale}/common.json`)).default, }));
3. Konfiguracja next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = {} const withNextIntl = require("next-intl/plugin")("./i18n.js"); =zNextIntl (następna konfiguracja)
5. Wdrażaj tłumaczenie
Kod w układzie.js:
importuj "./globals.css"; importuj { NextIntlClientProvider, useMessages } z 'next-intl'; importuj { locales } z '@/navigation'; importuj nagłówek z '@/components/Header' importuj stopkę z '@/components /Footer' domyślna funkcja eksportu RootLayout({dzieci, params: { locale } }) { if (!locales.includes(locale)) { notFound(); } const Messages = useMessages();
<html lang="{locale}">
<nextintlclientprovider locale="{locale}" messages="{messages}">
<body><header />{dzieci}<footer /></body>
</nextintlclientprovider>
</html>
);
}
Kod w page.js:
Parametr locale reprezentuje bieżący język.
Jeśli plik tłumaczenia nie jest zagnieżdżony, const t = useTranslations();
Jeśli plik tłumaczenia jest zagnieżdżony, użyj czegoś takiego: const t = useTranslations("bbb"); w oparciu o strukturę pliku i rzeczywiste potrzeby.
importuj { useTranslations } z 'next-intl'; importuj { Link } z '@/navigation'; eksportuj domyślną funkcję Home({ params: { locale } }) { const t = useTranslations();<>
<link href="{"/"}"><h1>{t("aaa")}</h1></Link>
</>)
6. Przełącznik języka
1. Efekt
Pociągnij w dół, aby wybrać język, a bieżąca strona przełączy się na stronę w wybranym języku.
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. Przyjazny dla SEO i wyszukiwarek
1. Metadane
Router Nextjs APP generuje tytuł i metadane strony. Wypróbowałem trzy metody:
Pierwszy sposób: użyj go bezpośrednio w układzie.js: expert const metadata={}
Drugi sposób: użyj dynamicznie generowanych metadanych w page.js
Na przykład:Optymalizacja: Metadane |. Next.js (nextjs.org)
Na te dwa sposoby nie udało mi się uzyskać wielojęzycznego tytułu i metadanych. Ostatecznie zastosowano trzecią metodę, która jest jednocześnie najprostszą i najbardziej bezpośrednią metodą.
Trzeci sposób: napisz tag tytułowy i metatag bezpośrednio w page.js.
Dlatego kod page.js został zmieniony na następujący:
importuj { useTranslations } z 'next-intl'; importuj { Link } z '@/navigation'; eksportuj domyślną funkcję Home({ params: { locale } }) { const t = useTranslations();<>
<title>{t("nazwa-witryny")}</title>
<meta name="keyword" content="{t("site-name")}"></meta>
<meta name="description" content="{t("opis-witryny")}"></meta>
<meta property="og:type" content="website"></meta>
<meta property="og:title" content="{t("nazwa-witryny")}"></meta>
<meta property="og:description" content="{t("opis-witryny")}"></meta>
<meta property="og:site_name" content="{t("nazwa-witryny")}"></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. Nawigacja wielojęzyczna: Ułatw wyszukiwarkom odnajdywanie wielojęzycznych adresów URL
zilustrować
Przełącznik języków jest renderowany od frontu, dlatego na dole strony dodałem renderowaną od tyłu wielojęzyczną nawigację, czyli komponent Footer.js. Kliknięcie na odpowiedni język spowoduje wyświetlenie strony głównej serwisu w tym języku.
Kod Footer.js wygląda następująco:
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. Podsumowanie
Międzynarodowy routing, struktura i wprowadzanie plików tłumaczeniowych oraz realizacja tłumaczeń. Bez względu na rodzaj planu internacjonalizacji, te trzy aspekty będą uwzględnione. Choć generalnie nie jest to kłopotliwe, next-intl jest stosunkowo proste.
9. Odniesienie
Głębokie zanurzenie się w lokalizację routera aplikacji Next.js za pomocą next-intl
Kompletny przewodnik dotyczący konfiguracji next-intl za pomocą routera aplikacji