You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Remix中使用Clerk实现本地化:App函数内如何配置localization?

在Remix的root.tsx中根据内部locale动态配置ClerkApp的localization参数

以下是当前的示例代码:

import { ClerkApp } from "@clerk/remix";
import { useLoaderData } from "@remix-run/react";
import { enUS, jaJP } from "@clerk/localizations";

interface LoaderData {
  locale: string;
}

function App() {
  const { locale } = useLoaderData<LoaderData>(); // 该值可由客户端修改

  return (
    <html lang={locale}>
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

const enLocalization = {
  ...enUS,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

const jaLocalization = {
  ...jaJP,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

// 如何根据用户浏览器语言设置本地化?

export default ClerkApp(App, { localization: enLocalization });

官方文档中ClerkApp的配置是在App函数外部完成的,但如果locale的校验逻辑位于App函数内部,该如何为ClerkApp设置localization参数?


解决方案

核心思路是将locale的确定逻辑移至root的loader中,并利用ClerkApp支持动态配置函数的特性,根据loader返回的locale数据自动切换本地化配置。

方法1:基于服务端loader动态配置(推荐)

这种方式能保证服务端渲染和客户端渲染的locale一致,适合从请求头、路由参数或用户会话中获取locale的场景:

import { ClerkApp } from "@clerk/remix";
import { useLoaderData } from "@remix-run/react";
import { enUS, jaJP } from "@clerk/localizations";
import type { LoaderFunctionArgs } from "@remix-run/node";

interface LoaderData {
  locale: string;
}

// 在loader中确定locale,支持从请求头、路由参数等来源获取
export async function loader({ request }: LoaderFunctionArgs) {
  // 示例:从请求头提取浏览器主语言
  const acceptLanguage = request.headers.get("Accept-Language");
  const rawLocale = acceptLanguage?.split(",")[0].split("-")[0] || "en";
  
  // 校验locale是否在支持列表中
  const supportedLocales = ["en", "ja"];
  return { locale: supportedLocales.includes(rawLocale) ? rawLocale : "en" };
}

function App() {
  const { locale } = useLoaderData<LoaderData>();

  return (
    <html lang={locale}>
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

const enLocalization = {
  ...enUS,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

const jaLocalization = {
  ...jaJP,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

// 使用函数形式的配置,根据loader数据动态选择本地化
export default ClerkApp(App, (data: LoaderData) => ({
  localization: data.locale === "ja" ? jaLocalization : enLocalization,
}));

方法2:客户端动态更新(适合用户手动切换场景)

如果locale需要在客户端通过交互切换(比如用户点击语言按钮),可以结合useClerk钩子动态更新本地化配置:

import { ClerkApp, useClerk } from "@clerk/remix";
import { useLoaderData, useEffect } from "@remix-run/react";
import { enUS, jaJP } from "@clerk/localizations";

interface LoaderData {
  locale: string;
}

function App() {
  const { locale } = useLoaderData<LoaderData>();
  const clerk = useClerk();

  // 当locale变化时,更新Clerk的本地化配置
  useEffect(() => {
    const targetLocalization = locale === "ja" ? jaLocalization : enLocalization;
    clerk.setLocalization(targetLocalization);
  }, [locale, clerk]);

  return (
    <html lang={locale}>
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

const enLocalization = {
  ...enUS,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

const jaLocalization = {
  ...jaJP,
  ...{
    signUp: { start: { subtitle: "{{applicationName}}" } },
  },
};

// 先设置默认本地化配置
export default ClerkApp(App, { localization: enLocalization });

内容的提问来源于stack exchange,提问作者Alpin Cleopatra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:23:22