Upgrade i18next v26 + react-i18next v17 with SSR-safe init
Split initI18n() into separate server/client initialization paths inspired by remix-i18next's architecture: - initI18nServer(lng): no LanguageDetector, per-request language from Accept-Language header - initI18nClient(): LanguageDetector reads <html lang> first to match server, then localStorage and navigator - detectLanguage(request): parses Accept-Language for best match Fixes rehydration errors caused by v26 removing initImmediate option (replaced with initAsync) and LanguageDetector running on the server where browser APIs don't exist. Also makes <html lang> dynamic instead of hardcoded "en". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4be716687a
commit
79f000fcc5
10 changed files with 166 additions and 40 deletions
|
|
@ -6,6 +6,7 @@ import { ServerRouter } from "react-router";
|
|||
import { isbot } from "isbot";
|
||||
import type { RenderToPipeableStreamOptions } from "react-dom/server";
|
||||
import { renderToPipeableStream } from "react-dom/server";
|
||||
import { initI18nServer, detectLanguage } from "@trails-cool/i18n";
|
||||
|
||||
const sentryEnvironment = process.env.CI ? "ci" : (process.env.NODE_ENV ?? "development");
|
||||
|
||||
|
|
@ -32,6 +33,8 @@ export default function handleRequest(
|
|||
routerContext: EntryContext,
|
||||
_loadContext: AppLoadContext,
|
||||
) {
|
||||
initI18nServer(detectLanguage(request));
|
||||
|
||||
if (request.method.toUpperCase() === "HEAD") {
|
||||
return new Response(null, {
|
||||
status: responseStatusCode,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue