Vite + React 集成

@lingo.dev/compiler 通过插件与 Vite 集成,支持 SPA 和 SSR 场景。

配置步骤

1. 安装依赖包

pnpm install @lingo.dev/compiler

2. 配置 Vite

在 Vite 配置中添加 lingoCompilerPlugin

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en",
      targetLocales: ["es", "de", "fr"],
      models: "lingo.dev",
      dev: {
        usePseudotranslator: true,
      },
    }),
    react(),
  ],
});

插件顺序: 请将 lingoCompilerPlugin 放在 react() 插件之前。这样可以确保编译器在 React 处理 JSX 之前完成转换。

3. 添加 Provider

在入口文件中用 LingoProvider 包裹你的应用:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { LingoProvider } from "@lingo.dev/compiler/react";
import App from "./App";
import "./index.css";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <App />
    </LingoProvider>
  </StrictMode>
);

重要提示: LingoProvider 应尽量放在组件树的顶层。如果使用 TanStack Router 或 React Router,请将 LingoProvider 放在路由 Provider 之上。

SPA 配置

对于单页应用,上述配置已足够。语言环境由客户端管理。

语言切换器

"use client";

import { useLingoContext } from "@lingo.dev/compiler/react";

export function LanguageSwitcher() {
  const { locale, setLocale } = useLingoContext();

  return (
    <div>
      <label>Language:</label>
      <select value={locale} onChange={(e) => setLocale(e.target.value)}>
        <option value="en">English</option>
        <option value="es">Español</option>
        <option value="de">Deutsch</option>
        <option value="fr">Français</option>
      </select>
    </div>
  );
}

SSR 配置(React Router、Remix、TanStack Start)

对于 SSR 框架,可能需要在服务端处理语言环境检测。

自定义语言环境检测

为服务端逻辑创建 .lingo/locale-resolver.server.ts

// .lingo/locale-resolver.server.ts
export async function getServerLocale(): Promise<string> {
  // Access request context (framework-specific)
  // Example: parse cookies, headers, or database
  return "en"; // Return detected locale
}

为客户端创建 .lingo/locale-resolver.client.ts

// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
  return localStorage.getItem("locale") || "en";
}

export function persistLocale(locale: string): void {
  localStorage.setItem("locale", locale);
}

参见 自定义语言环境解析器 获取各框架示例。

TanStack Router 集成

对于 TanStack Router,请将 LingoProvider 放在 RouterProvider 之上:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import { LingoProvider } from "@lingo.dev/compiler/react";
import { routeTree } from "./routeTree.gen";

const router = createRouter({ routeTree });

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <RouterProvider router={router} />
    </LingoProvider>
  </StrictMode>
);

这样可以确保在所有路由组件中都能使用翻译,并且代码分割不会破坏上下文。

React Router 集成

针对 React Router v6/v7:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { LingoProvider } from "@lingo.dev/compiler/react";
import App from "./App";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </LingoProvider>
  </StrictMode>
);

HMR 与开发

编译器完全支持 Vite 的热模块替换(HMR)。当你更新可翻译文本时:

  1. 编译器检测到变更
  2. 翻译服务器生成新翻译(或伪翻译)
  3. HMR 无需完全重载即可更新你的组件
  4. 组件状态得以保留

Fast Refresh 可正常工作——编译器不会干扰 Vite 的 HMR。

构建配置

开发构建

{
  dev: {
    usePseudotranslator: true, // Fast fake translations
  }
}

运行 npm run dev,即可通过伪翻译获得即时反馈。

生产构建

{
  buildMode: "cache-only", // Use pre-generated translations
}

运行 npm run build。翻译内容来自 .lingo/metadata.json——无需 API 调用。

最佳实践: 在生产构建前于 CI 中生成真实翻译。详见 构建模式

代码分割

编译器遵循 Vite 的代码分割策略。每个按需加载的 chunk 仅包含所需的翻译内容。

// Lazy-loaded route
const Dashboard = lazy(() => import("./pages/Dashboard"));

// Dashboard component's translations are bundled with the Dashboard chunk

翻译会自动进行 tree-shaking——每个 chunk 只包含实际用到的翻译。

TypeScript

编译器完全支持类型:

import type { LingoConfig } from "@lingo.dev/compiler";

const config: LingoConfig = {
  sourceRoot: "src",
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
};

环境变量

使用 Vite 的环境变量系统来管理 API 密钥:

# .env
VITE_LINGO_API_KEY=your_key_here

在配置中访问:

{
  models: "lingo.dev",
  // API key is automatically read from LINGODOTDEV_API_KEY env variable
}

切勿提交 API 密钥。 请将 .env 添加到 .gitignore

常见问题

“无法找到模块 '@lingo.dev/compiler/react'” 请确保已安装该包:pnpm install @lingo.dev/compiler

添加 LingoProvider 后 HMR 失效 请检查 lingoCompilerPlugin 是否位于 Vite 配置中 react() 插件之前。

生产环境下翻译未显示 请验证 buildMode: "cache-only",并确保 .lingo/metadata.json 包含所有语言的翻译。

代码分割导致上下文丢失 请确保 LingoProvider 位于路由提供器(TanStack Router、React Router 等)之上,否则代码分割路由可能会丢失上下文。

端口 60000 已被占用 翻译服务器会自动查找可用端口(60000-60099)。如全部被占用,请手动配置:

{
  dev: {
    translationServerStartPort: 61000, // Use different port range
  }
}

后续步骤