Lisab Next.js projektile täieliku mitmekeelsuse tugi next-intl abil.
Kogu oskus — vaikeversiooni hoitakse GitHubis; sinu muudatused jäävad sinu enda klooni.
Lisa Next.js (App Router) projektile täielik rahvusvahelistamine, kasutades next-intl v4. See oskus käsitleb marsruutimist, tõlkefaile, saidikaardi hreflangi ja hulgitõlget kõigisse lokaadidesse.
package.json) — peab olema 13+ App Routeriganext-intl, next-i18next, [locale] marsruute)npm install next-intl
Loo 4 faili kataloogi src/i18n/ alla:
src/i18n/config.tsexport const locales = ['en', 'es', 'fr', 'de', 'pt', 'ja', 'ar', 'zh', 'zh-tw', 'id', 'vi', 'ms', 'ru', 'hi'] as const
export type Locale = (typeof locales)[number]
export const defaultLocale: Locale = 'en'
export const localeNames: Record<Locale, string> = {
en: 'English',
es: 'Espanol',
fr: 'Francais',
de: 'Deutsch',
pt: 'Portugues',
ja: '日本語',
ar: 'العربية',
zh: '简体中文',
'zh-tw': '繁體中文',
id: 'Bahasa Indonesia',
vi: 'Tieng Viet',
ms: 'Bahasa Melayu',
ru: 'Русский',
hi: 'हिन्दी',
}
export const rtlLocales: Locale[] = ['ar']
src/i18n/routing.tsimport { defineRouting } from 'next-intl/routing'
import { defaultLocale, locales } from './config'
export const routing = defineRouting({
locales,
defaultLocale,
localePrefix: 'as-needed', // English URLs stay clean, other locales get /es/, /fr/, etc.
})
src/i18n/navigation.tsimport { createNavigation } from 'next-intl/navigation'
import { routing } from './routing'
export const { Link, redirect, usePathname, useRouter } = createNavigation(routing)
src/i18n/request.tsimport { getRequestConfig } from 'next-intl/server'
import { routing } from './routing'
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale
if (!locale || !routing.locales.includes(locale as any)) {
locale = routing.defaultLocale
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default,
}
})
Loo src/middleware.ts:
import createMiddleware from 'next-intl/middleware'
import { routing } from '@/i18n/routing'
export default createMiddleware({
...routing,
localeDetection: false, // Don't auto-redirect based on Accept-Language
})
export const config = {
matcher: ['/((?!_next|api|images|fonts|favicon|sitemap|robots).*)'],
}
Võtmeotsus: localeDetection: false takistab kasutajate automaatset ümbersuunamist brauserikeele põhjal. See hoiab ingliskeelsed URL-id SEO jaoks stabiilsena. Kasutajad saavad keelt käsitsi vahetada keelevalija kaudu.
Mässi olemasolev konfiguratsioon createNextIntlPlugin abil:
import createNextIntlPlugin from 'next-intl/plugin'
const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts')
// ... existing config ...
export default withNextIntl(nextConfig)
[locale] dünaamiline marsruutLiiguta kogu lehesisu src/app/[locale]/ alla:
Loo src/app/[locale]/layout.tsx koos:
- generateStaticParams(), mis tagastab kõik lokaadid
- setRequestLocale(locale) kutsega
- <NextIntlClientProvider> laste ümber
- <html lang={locale} dir={rtlLocales.includes(locale) ? 'rtl' : 'ltr'}>
- Hreflangi <link> märgendid <head>-is kõigile lokaadidele + x-default
Liiguta olemasolevad lehed src/app/[locale]/ alla
setRequestLocale(locale)Loo src/messages/en.json kõigi kasutajale nähtavate stringidega, organiseeritud sektsiooni järgi:
json
{
"common": { "signIn": "Sign In", ... },
"tools": { "tool-slug": { "title": "...", "description": "..." } },
"faq": { "tool-slug": [{ "question": "...", "answer": "..." }] }
}
Asenda kõik kõvakodeeritud stringid komponentides useTranslations() abil:
typescript
const t = useTranslations('common')
return <button>{t('signIn')}</button>
Serverikomponentide jaoks kasuta getTranslations():
typescript
const t = await getTranslations('common')
Iga mitte-inglise lokaadi jaoks loo src/messages/{locale}.json sama struktuuriga nagu en.json.
Kasuta paralleelseid Codex agente codex-tasks oskuse kaudu, et säästa Claude krediite:
/codex-tasksen.json, tõlgib kõik stringid, kirjutab {locale}.jsonen.json sisu (või teed selle lugemiseks)
- Sihtkeele nime ja lokaadikoodi
- Juhiseid:{count}, {name} muutumatunasrc/messages/{locale}.jsonPärast tõlget käivita kontrolliskript, et probleeme kinni püüda:
import json
locales = ['es', 'fr', 'de', 'pt', 'ja', 'ar', 'zh', 'zh-tw', 'id', 'vi', 'ms', 'ru', 'hi']
english_words = ['the ', 'and ', 'you ', 'your ', 'our ', 'this ', 'that ', 'with ', 'from ', 'will ']
with open('src/messages/en.json') as f:
en = json.load(f)
for loc in locales:
with open(f'src/messages/{loc}.json') as f:
data = json.load(f)
# Check: missing sections
missing = [s for s in en if s not in data]
# Check: residual English content
eng_count = 0
def check(d):
nonlocal eng_count # won't work in inline script; use list trick
if isinstance(d, dict):
for v in d.values(): check(v)
elif isinstance(d, str):
if sum(1 for w in english_words if w in d.lower()) >= 3:
eng_count += 1
check(data)
status = 'OK' if not missing and eng_count == 0 else 'ISSUES'
print(f'{loc}: {status} (missing={len(missing)}, english={eng_count})')
Uuenda src/app/sitemap.ts, et kaasata hreflangi alternates:
import { MetadataRoute } from 'next'
import { locales } from '@/i18n/config'
const baseUrl = 'https://www.example.com'
function buildAlternates(path: string): Record<string, string> {
const alternates: Record<string, string> = {}
for (const locale of locales) {
const prefix = locale === 'en' ? '' : `/${locale}`
alternates[locale] = `${baseUrl}${prefix}${path}`
}
return alternates
}
export default function sitemap(): MetadataRoute.Sitemap {
return pages.map((path) => ({
url: `${baseUrl}${path}`,
lastModified: new Date(),
alternates: { languages: buildAlternates(path) },
}))
}
Oluline: Genereeri üks kanooniline URL lehe kohta hreflangi alternates’idega, MITTE üks URL lokaadi kohta. See takistab duplikaatsisu otsingutulemustes.
Lisa keelevahetaja komponent, mis kasutab useRouter ja usePathname moodulist @/i18n/navigation, et vahetada lokaade, säilitades praeguse tee.
npm run build — kontrolli, et kõik staatilised lehed genereeruvad õigestihttps://example.com/toolshttps://example.com/es/toolspublic/sitemap.xml konfliktib dünaamilise src/app/sitemap.ts-iga arendusrežiimis — kustuta staatiline või nimeta ümber_next, api, sitemap, robots ja staatiliste varade teedlocalePrefix: 'as-needed' on kriitiline — see hoiab vaikimisi lokaadi URL-id SEO järjepidevuse jaoks puhtanalocaleDetection: false takistab soovimatuid ümbersuunamisi, mis murravad SEO-d ja ajavad kasutajaid segadussegit config http.postBuffer 524288000