Vite + React統合

@lingo.dev/compilerは、SPAとSSRの両方のセットアップで動作するプラグインを通じてViteと統合されます。

セットアップ

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(),
  ],
});

プラグインの順序: lingoCompilerPluginreact()プラグインの前に配置してください。これにより、コンパイラがReactが処理する前にJSXを変換します。

3. プロバイダーの追加

エントリーポイントで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をルータープロバイダーの上に配置してください。

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の場合、LingoProviderRouterProviderの上に配置します:

// 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のコード分割を尊重します。各遅延ロードされたチャンクには、必要な翻訳のみが含まれます。

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

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

翻訳は自動的にツリーシェイキングされます—使用される翻訳のみが各チャンクに含まれます。

TypeScript

コンパイラは完全に型付けされています:

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

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

環境変数

APIキーにはViteの環境変数システムを使用します。

# .env
VITE_LINGO_API_KEY=your_key_here

設定でアクセス:

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

APIキーは絶対にコミットしないでください。 .gitignore.envを追加してください。

よくある問題

「モジュール'@lingo.dev/compiler/react'が見つかりません」 パッケージがインストールされていることを確認してください: pnpm install @lingo.dev/compiler

LingoProviderを追加後にHMRが動作しなくなる Vite設定でlingoCompilerPluginreact()プラグインの前に配置されていることを確認してください。

本番環境で翻訳が表示されない buildMode: "cache-only"と、.lingo/metadata.jsonにすべてのロケールの翻訳が含まれていることを確認してください。

コード分割でコンテキストが壊れる LingoProviderがルータープロバイダー(TanStack Router、React Routerなど)の上に配置されていることを確認してください。そうでない場合、コード分割されたルートでコンテキストが失われる可能性があります。

ポート60000が既に使用中 翻訳サーバーは自動的に利用可能なポート(60000-60099)を検索します。すべて使用中の場合は、手動で設定してください:

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

次のステップ