コンテンツにスキップ

Vendure Dashboard 日本語化手順書

概要

このドキュメントでは、Vendure React Dashboardの日本語化(国際化)の設定方法と、新しい翻訳キーを追加する手順を説明します。

重要な前提知識:

  • Vendure Dashboard 3.5.1には4936行の日本語翻訳が既に含まれています
  • 標準UIの翻訳は @vendure/dashboard パッケージに同梱されており、追加作業不要です
  • カスタムDashboard拡張を作成する場合のみ、Linguiを使用した翻訳作業が必要です

Dashboard開発全般: カスタムページの作成、コンポーネントの追加、データ連携などの詳細については Vendure開発ハンドブック - Dashboard開発 を参照してください。

参考資料


第1部: デフォルト言語の設定(標準UI日本語化)

Vendure Dashboard標準UIを日本語で表示するための設定方法です。

前提条件

  • Vendure 3.5.1以降がインストール済み
  • DashboardPluginが vendure-config.ts に設定済み

設定手順

ステップ1: Vendure設定でデフォルト言語を指定

ファイル: apps/vendure-server/src/vendure-config.ts

import { LanguageCode, type VendureConfig } from '@vendure/core';

export const config: VendureConfig = {
  defaultLanguageCode: LanguageCode.ja,
  // ... 他の設定
};

説明:

  • defaultLanguageCodeLanguageCode.ja に設定することで、Vendure全体のデフォルト言語が日本語になります
  • この設定は新規作成されるチャネルに適用されます

ステップ2: 既存チャネルのデフォルト言語を更新

既にチャネルが存在する場合、データベースマイグレーションで更新します。

ファイル: apps/vendure-server/src/migrations/set-default-language-to-ja1731890000000.ts

import { MigrationInterface, QueryRunner } from 'typeorm';

export class SetDefaultLanguageToJa1731890000000 implements MigrationInterface {
  name = 'SetDefaultLanguageToJa1731890000000';

  public async up(queryRunner: QueryRunner): Promise<void> {
    // チャネルのデフォルト言語を日本語に更新
    await queryRunner.query(`
      UPDATE channel
      SET "defaultLanguageCode" = 'ja'
      WHERE "defaultLanguageCode" IS DISTINCT FROM 'ja'
    `);

    // 利用可能言語に日本語を追加
    await queryRunner.query(`
      UPDATE channel
      SET "availableLanguageCodes" = CASE
        WHEN "availableLanguageCodes" IS NULL OR "availableLanguageCodes" = '' THEN 'ja'
        WHEN POSITION('ja' IN "availableLanguageCodes") = 0 THEN "availableLanguageCodes" || ',ja'
        ELSE "availableLanguageCodes"
      END
    `);

    console.log('✅ Default language for channels set to Japanese (ja)');
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      UPDATE channel
      SET "defaultLanguageCode" = 'en'
      WHERE "defaultLanguageCode" = 'ja'
    `);

    await queryRunner.query(`
      UPDATE channel
      SET "availableLanguageCodes" = 'en'
      WHERE "availableLanguageCodes" IN ('ja', 'en,ja', 'ja,en')
    `);

    console.log('✅ Default language for channels reverted to English');
  }
}

実行方法:

cd apps/vendure-server
pnpm run migration:run

ステップ3: 既存ユーザー設定を日本語に更新

既にDashboardを使用しているユーザーの言語設定を日本語に更新します。

ファイル: apps/vendure-server/src/migrations/1731891000000-update-dashboard-user-settings-to-japanese.ts

import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Updates existing dashboard user settings to use Japanese as the default language.
 * This ensures that all users see the dashboard in Japanese by default.
 */
export class UpdateDashboardUserSettingsToJapanese1731891000000
  implements MigrationInterface
{
  name = 'UpdateDashboardUserSettingsToJapanese1731891000000';

  public async up(queryRunner: QueryRunner): Promise<void> {
    // Update existing user settings to Japanese
    await queryRunner.query(`
      UPDATE settings_store_entry
      SET value = jsonb_set(
        jsonb_set(
          value::jsonb,
          '{displayLanguage}',
          '"ja"'
        ),
        '{contentLanguage}',
        '"ja"'
      )
      WHERE key = 'vendure.dashboard.userSettings'
        AND (
          value::jsonb->>'displayLanguage' != 'ja'
          OR value::jsonb->>'contentLanguage' != 'ja'
        )
    `);

    console.log('✅ Dashboard user settings updated to Japanese');
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    // Revert to English if needed
    await queryRunner.query(`
      UPDATE settings_store_entry
      SET value = jsonb_set(
        jsonb_set(
          value::jsonb,
          '{displayLanguage}',
          '"en"'
        ),
        '{contentLanguage}',
        '"en"'
      )
      WHERE key = 'vendure.dashboard.userSettings'
        AND (
          value::jsonb->>'displayLanguage' = 'ja'
          OR value::jsonb->>'contentLanguage' = 'ja'
        )
    `);

    console.log('✅ Dashboard user settings reverted to English');
  }
}

実行方法:

cd apps/vendure-server
pnpm run migration:run

説明:

  • settings_store_entry テーブルには、各ユーザーのDashboard設定が保存されています
  • displayLanguage: UI表示言語
  • contentLanguage: コンテンツ(商品名等)の言語
  • このマイグレーションで既存ユーザーの設定を一括更新します

ステップ4: Dashboardをビルド

cd apps/vendure-server
pnpm run dashboard:build

ステップ5: 動作確認

  1. サーバーを起動:
pnpm run dev:local
  1. ブラウザで http://localhost:3021/dashboard/ にアクセス

  2. サイドバー、メニュー、すべてのUI要素が日本語で表示されることを確認

設定の仕組み

Vendure Dashboardの言語設定は以下の優先順位で決定されます:

  1. ユーザー設定 (settings_store_entry テーブル)
  2. ユーザーが明示的に選択した言語
  3. Dashboard右上メニューから変更可能

  4. チャネル設定 (channel テーブル)

  5. チャネルの defaultLanguageCode
  6. ユーザー設定がない場合のフォールバック

  7. Vendure設定 (vendure-config.ts)

  8. defaultLanguageCode
  9. 新規チャネル作成時のデフォルト値

上記3つのステップで、これらすべてを日本語に設定することで、確実に日本語Dashboardが表示されます。

トラブルシューティング

問題: Dashboardが英語のまま表示される

原因: ブラウザのlocalStorageに古い設定が残っている

解決方法:

  1. ブラウザの開発者ツールを開く(F12)
  2. Application → Local Storage → http://localhost:3021 を選択
  3. vendure.dashboard.userSettings キーを削除
  4. ページをリロード

問題: マイグレーション実行時にエラーが発生

原因: settings_store_entry テーブルが存在しない

解決方法: DashboardPluginが正しく設定されているか確認してください。DashboardPluginは初回起動時に settings_store_entry テーブルを自動作成します。

// vendure-config.ts
import { DashboardPlugin } from '@vendure/dashboard/plugin';

export const config: VendureConfig = {
  plugins: [
    DashboardPlugin.init({
      route: 'dashboard',
      appDir: join(__dirname, '../dist/dashboard'),
    }),
    // ... 他のプラグイン
  ],
};

第2部: カスタムDashboard拡張の翻訳(Lingui使用)

カスタムDashboard拡張を作成する場合、Linguiを使用して翻訳を管理します。

前提条件

  • @lingui/cli, @lingui/macro, @lingui/vite-plugin がインストール済み
  • Vendure Dashboard Plugin が設定済み

現在の設定状況

ファイル構成

apps/vendure-server/
├── lingui.config.js              # Lingui設定ファイル
├── vite.config.mts              # Vite設定(Linguiプラグイン含む)
├── src/
│   ├── dashboard/
│   │   ├── index.tsx            # カスタムDashboardコンポーネント
│   │   └── i18n/
│   │       ├── ja.po            # 日本語翻訳ファイル(カスタム拡張用)
│   │       └── en.po            # 英語翻訳ファイル(カスタム拡張用)
│   └── i18n/
│       └── {locale}/messages/   # サーバー側翻訳(既存)

設定ファイル

lingui.config.js:

const { defineConfig } = require('@lingui/cli');

module.exports = defineConfig({
  sourceLocale: 'ja',
  locales: ['ja', 'en'],
  catalogs: [
    // Dashboard拡張用のカタログ
    {
      path: '<rootDir>/src/dashboard/i18n/{locale}',
      include: ['<rootDir>/src/dashboard/**'],
    },
    // 既存のサーバー側翻訳用カタログ
    {
      path: '<rootDir>/src/i18n/{locale}/messages',
      include: ['<rootDir>/src'],
      exclude: ['<rootDir>/src/dashboard/**'],
    },
  ],
  format: 'po',
  fallbackLocales: {
    default: 'ja',
  },
});

vite.config.mts:

import { lingui } from '@lingui/vite-plugin';
import { vendureDashboardPlugin } from '@vendure/dashboard/vite';
import { join, resolve } from 'path';
import { pathToFileURL } from 'url';
import { defineConfig } from 'vite';

export default defineConfig({
  base: '/dashboard/',
  build: {
    outDir: join(__dirname, 'dist/dashboard'),
  },
  plugins: [
    lingui(),
    vendureDashboardPlugin({
      vendureConfigPath: pathToFileURL('./src/vendure-config.ts'),
      api: {
        host: 'http://localhost',
        port: 3021,
      },
      gqlOutputPath: resolve(__dirname, './src/gql/'),
    }),
  ],
});

カスタム拡張の翻訳手順

ステップ1: コンポーネントで文字列をラップする

カスタムDashboardコンポーネント内の翻訳対象文字列を Trans コンポーネントまたは useLingui フックでラップします。

Transコンポーネントを使用(推奨):

import { Trans } from '@lingui/react/macro';

function MyCustomComponent() {
  return (
    <div>
      <h1>
        <Trans>Welcome to Custom Dashboard</Trans>
      </h1>
    </div>
  );
}

useLinguiフックを使用(動的文字列):

import { useLingui } from '@lingui/react/macro';

function MyCustomComponent() {
  const { t } = useLingui();

  return (
    <div>
      <p>{t`Click here to continue`}</p>
    </div>
  );
}

ステップ2: 翻訳キーを抽出する

コンポーネント内の Transt でラップした文字列を .po ファイルに抽出します。

cd apps/vendure-server
npx lingui extract

このコマンドを実行すると、src/dashboard/i18n/ ディレクトリに以下のファイルが生成・更新されます:

  • ja.po - 日本語翻訳ファイル(sourceLocale)
  • en.po - 英語翻訳ファイル

実行結果の例:

Catalog statistics for src/dashboard/i18n/{locale}:
✔ Done in 869ms
┌─────────────┬─────────────┬─────────┐
│ Language    │ Total count │ Missing │
├─────────────┼─────────────┼─────────┤
│ ja (source) │      9      │    -    │
│ en          │      9      │    2    │
└─────────────┴─────────────┴─────────┘

Missing カラムに未翻訳のキー数が表示されます。

ステップ3: 翻訳を追加・編集する

生成された .po ファイルを編集して、各言語の翻訳を追加します。

例: src/dashboard/i18n/ja.po

#: src/dashboard/index.tsx:17
msgid "Welcome to Custom Dashboard"
msgstr "カスタムダッシュボードへようこそ"

例: src/dashboard/i18n/en.po

#: src/dashboard/index.tsx:17
msgid "Welcome to Custom Dashboard"
msgstr "Welcome to Custom Dashboard"

ステップ4: 翻訳をコンパイルする

.po ファイルを編集した後、コンパイルして実行時に使用可能な形式に変換します。

cd apps/vendure-server
npx lingui compile

ステップ5: Dashboardをビルドする

翻訳を反映するために、Dashboardを再ビルドします。

pnpm run dashboard:build

開発環境の場合:

pnpm run dashboard:dev

ステップ6: 動作確認

  1. サーバーを起動:
pnpm run dev:local
  1. ブラウザで http://localhost:3021/dashboard/ にアクセス

  2. カスタムコンポーネントの文字列が日本語で表示されることを確認


第3部: 高度な使用例

変数を含む翻訳

import { useLingui } from '@lingui/react/macro';

function OrderSummary({ count }: { count: number }) {
  const { t } = useLingui();

  return <p>{t`You have ${count} orders`}</p>;
}

翻訳ファイル:

msgid "You have {count} orders"
msgstr "{count}件の注文があります"

複数形の処理

import { Trans } from '@lingui/react/macro';

function ItemCount({ count }: { count: number }) {
  return (
    <Trans>
      {count, plural,
        =0 {No items}
        one {# item}
        other {# items}
      }
    </Trans>
  );
}

翻訳ファイル:

msgid "{count, plural, =0 {No items} one {# item} other {# items}}"
msgstr "{count, plural, =0 {アイテムなし} one {#個のアイテム} other {#個のアイテム}}"

プラグインのDashboard拡張を翻訳する場合

カスタムプラグインにDashboard拡張がある場合、lingui.config.js に新しいカタログエントリを追加します。

例: packages/plugins/customer-management/ にDashboard拡張がある場合

const { defineConfig } = require('@lingui/cli');

module.exports = defineConfig({
  sourceLocale: 'ja',
  locales: ['ja', 'en'],
  catalogs: [
    // 既存のDashboard拡張用カタログ
    {
      path: '<rootDir>/src/dashboard/i18n/{locale}',
      include: ['<rootDir>/src/dashboard/**'],
    },
    // カスタムプラグインのDashboard拡張用カタログ
    {
      path: '<rootDir>/../../packages/plugins/customer-management/src/ui/i18n/{locale}',
      include: [
        '<rootDir>/../../packages/plugins/customer-management/src/ui/**',
      ],
    },
    // 既存のサーバー側翻訳用カタログ
    {
      path: '<rootDir>/src/i18n/{locale}/messages',
      include: ['<rootDir>/src'],
      exclude: ['<rootDir>/src/dashboard/**'],
    },
  ],
  format: 'po',
  fallbackLocales: {
    default: 'ja',
  },
});

よくある質問(FAQ)

Q1: 標準UIの翻訳が反映されない

原因: ユーザー設定またはチャネル設定が英語のまま

解決方法:

  1. 第1部の「デフォルト言語の設定」を確認
  2. マイグレーションを実行: pnpm run migration:run
  3. ブラウザのlocalStorageをクリア(開発者ツール → Application → Local Storage → vendure.dashboard.userSettings を削除)
  4. Dashboardをリビルド: pnpm run dashboard:build

Q2: カスタム拡張の翻訳が反映されない

原因: 翻訳の抽出・コンパイル・ビルドのいずれかが実行されていない

解決方法:

cd apps/vendure-server
npx lingui extract     # 翻訳キーを抽出
npx lingui compile     # 翻訳をコンパイル
pnpm run dashboard:build  # Dashboardをビルド

Q3: 複数のコンポーネントで同じ文字列を使いたい

回答: msgid が同じであれば、1つの翻訳エントリで複数のコンポーネントに対応できます。Linguiは自動的に同じ msgid を統合します。

Q4: ビルド時に「Missing translations」警告が出る

原因: .po ファイルの msgstr が空

解決方法: .po ファイルを開き、すべての msgstr に翻訳を追加してください。

Q5: マイグレーション実行時にエラーが発生

原因: settings_store_entry テーブルが存在しない

解決方法: DashboardPluginが正しく設定されているか確認してください。DashboardPluginは初回起動時に settings_store_entry テーブルを自動作成します。

// vendure-config.ts
import { DashboardPlugin } from '@vendure/dashboard/plugin';

export const config: VendureConfig = {
  plugins: [
    DashboardPlugin.init({
      route: 'dashboard',
      appDir: join(__dirname, '../dist/dashboard'),
    }),
    // ... 他のプラグイン
  ],
};

ベストプラクティス

1. 翻訳キーの命名規則

  • 具体的な文脈を含める: "Save" ではなく "Save Product" のように具体的に
  • 一貫性を保つ: 同じ意味の文字列は同じ msgid を使用
  • 短く明確に: 長すぎる文字列は避け、必要に応じて分割

2. 翻訳ファイルの管理

  • 定期的にextract: コンポーネント追加後は必ず npx lingui extract を実行
  • 未翻訳を確認: Missing カラムをチェックし、すべての翻訳を完了
  • バージョン管理: .po ファイルはGitで管理し、変更履歴を残す

3. 開発ワークフロー

# 1. コンポーネントに Trans/t を追加
# 2. 翻訳キーを抽出
npx lingui extract

# 3. .po ファイルを編集して翻訳を追加
# 4. 翻訳をコンパイル
npx lingui compile

# 5. 開発サーバーで確認(ホットリロード対応)
pnpm run dashboard:dev

# 6. 本番ビルド
pnpm run dashboard:build

4. 避けるべきパターン

ハードコードされた文字列:

// 悪い例
<h1>Welcome to Dashboard</h1>

Transでラップ:

// 良い例
<h1>
  <Trans>Welcome to Dashboard</Trans>
</h1>

文字列の連結:

// 悪い例
{
  t`You have ` + count + t` items`;
}

変数を含む翻訳:

// 良い例
{
  t`You have ${count} items`;
}

Vendure標準UIの日本語翻訳について

翻訳の詳細

  • 翻訳ファイル: node_modules/@vendure/dashboard/src/i18n/locales/ja.po
  • 翻訳数: 4936行
  • 対象: すべての標準UI(Insights、Catalog、Sales、Customers、Marketing、Administration、System等)
  • メンテナンス: Vendureコアチームが公式に管理

ビルド出力の確認

ビルドが成功すると、以下のファイルが生成されます:

dist/dashboard/assets/i18n/ja.js  (52.87 kB)

このファイルには、Vendure公式の日本語翻訳がすべて含まれています。

翻訳の品質

Vendure公式の日本語翻訳は高品質で、以下の要素が含まれます:

  • UI要素(ボタン、ラベル、メニュー等)
  • エラーメッセージ
  • 確認ダイアログ
  • フォームバリデーション
  • ヘルプテキスト

まとめ

標準UI日本語化の3ステップ

  1. vendure-config.ts: defaultLanguageCode: LanguageCode.ja
  2. チャネルマイグレーション: channel.defaultLanguageCode = 'ja'
  3. ユーザー設定マイグレーション: settings_store_entry を更新

カスタム拡張翻訳の5ステップ

  1. Trans/tでラップ: コンポーネント内の文字列を翻訳可能に
  2. extract: npx lingui extract.po ファイルを生成
  3. 翻訳追加: .po ファイルの msgstr に翻訳を記述
  4. compile: npx lingui compile で実行時形式に変換
  5. ビルド: pnpm run dashboard:build で反映

重要な注意事項

  • 標準UIは追加作業不要: Vendure公式の日本語翻訳が自動適用されます
  • カスタム拡張のみLingui使用: 独自コンポーネントを作成する場合のみ翻訳作業が必要
  • 設定の優先順位: ユーザー設定 > チャネル設定 > Vendure設定

更新履歴

  • 2025-11-18: 初版作成(Vendure公式ドキュメントに基づく実装)
  • 2025-11-18: Vendure標準UIの日本語翻訳について追記
  • 2025-11-18: 完全版に更新(デフォルト言語設定の詳細、トラブルシューティング、ベストプラクティスを追加)