frontend-internationalization-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseInternationalization Best Practices
国际化最佳实践
Guidelines for building a React Router i18n setup with . Focuses on middleware detection, locale storage, type safety, and client/server synchronization.
remix-i18next本指南介绍如何使用搭建React Router国际化配置,重点涵盖中间件检测、语言环境存储、类型安全以及客户端/服务端同步。
remix-i18nextWhen to Apply
适用场景
- Adding i18n to a React Router app
- Wiring middleware
remix-i18next - Implementing language switching or locale detection
- Serving locale resources from
/api/locales
- 为React Router应用添加国际化功能
- 配置中间件
remix-i18next - 实现语言切换或语言环境检测
- 通过提供语言环境资源
/api/locales
Rules Summary
规则摘要
Setup & Middleware (CRITICAL)
配置与中间件(关键)
setup-middleware - @rules/setup-middleware.md
setup-middleware - @rules/setup-middleware.md
Configure and type-safe resources.
createI18nextMiddlewarets
export const [i18nextMiddleware, getLocale, getInstance] =
createI18nextMiddleware({
detection: {
supportedLanguages: ["es", "en"],
fallbackLanguage: "en",
cookie: localeCookie,
},
i18next: { resources },
plugins: [initReactI18next],
});配置和类型安全的资源文件。
createI18nextMiddlewarets
export const [i18nextMiddleware, getLocale, getInstance] =
createI18nextMiddleware({
detection: {
supportedLanguages: ["es", "en"],
fallbackLanguage: "en",
cookie: localeCookie,
},
i18next: { resources },
plugins: [initReactI18next],
});locales-structure - @rules/locales-structure.md
locales-structure - @rules/locales-structure.md
Define locale resources per language and re-export.
ts
// app/locales/en/translation.ts
export default { title: "Example" };按语言定义语言环境资源并重新导出。
ts
// app/locales/en/translation.ts
export default { title: "Example" };Namespaces (HIGH)
命名空间(重要)
namespaces-strategy - @rules/namespaces-strategy.md
namespaces-strategy - @rules/namespaces-strategy.md
Use a single namespace for small apps; multiple namespaces for large apps.
ts
// Large app: common + route namespaces
export default { common, home, notFound };小型应用使用单一命名空间;大型应用使用多命名空间。
ts
// 大型应用:通用 + 路由命名空间
export default { common, home, notFound };Locale Detection & Persistence (CRITICAL)
语言环境检测与持久化(关键)
locale-detection - @rules/locale-detection.md
locale-detection - @rules/locale-detection.md
Prefer cookie/session for speed, with DB as source of truth.
ts
export const [i18nextMiddleware, getLocale] = createI18nextMiddleware({
detection: { cookie: localeCookie, fallbackLanguage: "en" },
});优先使用Cookie/会话以提升速度,数据库作为可信数据源。
ts
export const [i18nextMiddleware, getLocale] = createI18nextMiddleware({
detection: { cookie: localeCookie, fallbackLanguage: "en" },
});language-switcher - @rules/language-switcher.md
language-switcher - @rules/language-switcher.md
Store locale in cookie/session and keep it in sync.
ts
return data(
{ locale },
{ headers: { "Set-Cookie": await localeCookie.serialize(locale) } },
);将语言环境存储在Cookie/会话中并保持同步。
ts
return data(
{ locale },
{ headers: { "Set-Cookie": await localeCookie.serialize(locale) } },
);Client & Server Integration (CRITICAL)
客户端与服务端集成(关键)
root-locale-sync - @rules/root-locale-sync.md
root-locale-sync - @rules/root-locale-sync.md
Send locale to the UI and sync .
<html lang dir>tsx
export async function loader({ context }: Route.LoaderArgs) {
let locale = getLocale(context);
return data(
{ locale },
{ headers: { "Set-Cookie": await localeCookie.serialize(locale) } },
);
}将语言环境传递至UI并同步属性。
<html lang dir>tsx
export async function loader({ context }: Route.LoaderArgs) {
let locale = getLocale(context);
return data(
{ locale },
{ headers: { "Set-Cookie": await localeCookie.serialize(locale) } },
);
}entry-client-init - @rules/entry-client-init.md
entry-client-init - @rules/entry-client-init.md
Initialize i18next client with detection.
htmlTagts
i18next.init({ detection: { order: ["htmlTag"], caches: [] } });通过检测初始化i18next客户端。
htmlTagts
i18next.init({ detection: { order: ["htmlTag"], caches: [] } });entry-server-provider - @rules/entry-server-provider.md
entry-server-provider - @rules/entry-server-provider.md
Reuse the middleware instance in SSR with .
I18nextProvidertsx
<I18nextProvider i18n={getInstance(routerContext)}>
<ServerRouter context={entryContext} url={request.url} />
</I18nextProvider>在SSR中通过复用中间件实例。
I18nextProvidertsx
<I18nextProvider i18n={getInstance(routerContext)}>
<ServerRouter context={entryContext} url={request.url} />
</I18nextProvider>Resource Routes & Caching (HIGH)
资源路由与缓存(重要)
locales-resource-route - @rules/locales-resource-route.md
locales-resource-route - @rules/locales-resource-route.md
Serve with validation and cache headers.
/api/locales/:lng/:nsts
return data(namespaces[ns.data], { headers });提供接口并添加验证和缓存头。
/api/locales/:lng/:nsts
return data(namespaces[ns.data], { headers });UI Usage (MEDIUM)
UI使用(中等)
use-bound-t-in-loader - @rules/use-bound-t-in-loader.md
use-bound-t-in-loader - @rules/use-bound-t-in-loader.md
Use the bound in loaders and in components.
t()useTranslationts
let t = getInstance(context).getFixedT(locale);在加载器中使用绑定的,在组件中使用。
t()useTranslationts
let t = getInstance(context).getFixedT(locale);Not Found (MEDIUM)
404页面处理(中等)
not-found-i18n - @rules/not-found-i18n.md
not-found-i18n - @rules/not-found-i18n.md
Provide a 404 route so middleware runs and translations load.
提供404路由以确保中间件运行并加载翻译内容。