Translator API

ブラウザ内蔵の翻訳機能


概要

- `Translator API` を使うことで、ブラウザ内蔵の翻訳機能を使うことが可能 - ChromeのビルトインGemini nanoを使って翻訳 - 2025/07/02現在、PC版のChrome 138 以降でのみ利用可能

デモ

Translator API サンプル


結果

ポイント

| 項目 | ポイント | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | **対応環境** | *Chrome 138 以降*、デスクトップのみ。モバイル Chrome は未対応 | | **セキュリティ** | Secure Context(HTTPS または `localhost`)必須。HTTP では `Translator` が未定義 ([Stack Overflow][2]) | | **ハードウェア要件** | Windows 10/11・macOS 13+・Linux、
VRAM > 4 GB、Chrome プロファイルのあるドライブに *22 GB 以上* の空き。空きが 10 GB 未満になるとモデルは自動削除 | | **機能検出** | `if ('Translator' in self) { … }` でサポート確認 | | **言語ペアの可用性** | `Translator.availability()` → `'unavailable' / 'downloadable' / 'downloading' / 'available'` の 4 値を返す | | **インスタンス生成** | `Translator.create({ sourceLanguage, targetLanguage, monitor })` で生成。`monitor` で `downloadprogress` を監視し UI に進捗表示 | | **翻訳実行** | `await translator.translate(text)` で翻訳。処理は逐次実行→大量テキストはチャンク化推奨 | | **言語コード** | BCP-47 形式(例: `ja`, `en`, `zh-Hant`)を使用 | | **他 API 連携** | ソース言語不明時は Language Detector API → Translator API の順が便利 | | **UX 改善** | ①モデル DL 中/翻訳中のステータス表示
②エラー時に空き容量やネット状況を案内
③モデルは一度 DL すればキャッシュされ 2 回目以降高速 | | **プライバシー / コスト** | 翻訳は完全に *端末内* で完結 → テキストをクラウドへ送信しない。外部翻訳 API の利用料も不要 |

コード

JavaScript

const input   = document.getElementById('input');      // 元文
const output  = document.getElementById('output');     // 結果
const status  = document.getElementById('status');     // ステータス
const srcLang = document.getElementById('srcLang');

/**
  * Translator オブジェクトを生成
  * 
  * @param {string} src - ソース言語コード(BCP-47形式)
  * @param {string} tgt - ターゲット言語コード(BCP-47形式)
  * @returns {Promise} - Translator オブジェクト
  */
async function createTranslator(src, tgt) {
  // ① 言語ペア対応状況を確認
  const availability = await Translator.availability({ sourceLanguage: src, targetLanguage: tgt });
  if (availability === 'unavailable') throw new Error('この言語ペアは未対応です。');

  // ② Translator オブジェクト生成(モデル DL 進捗を監視)
  return await Translator.create({
    sourceLanguage: src,
    targetLanguage: tgt,
    monitor(m) {
      m.addEventListener('downloadprogress', e => {
        status.textContent = `モデルをダウンロード中… ${(e.loaded * 100).toFixed(0)} %`;
      });
    }
  });
}

// 大量テキストを 2 kB ごとにチャンクして逐次翻訳
/*
async function translateLarge(text, translator, size = 2048) {
  for (const chunk of text.match(new RegExp(`(.|[\\r\\n]){1,${size}}`, 'g'))) {
    document.getElementById('output').value += await translator.translate(chunk);
  }
}
*/

// localhost以外でのHTTPアクセス時の早期リジェクト
/*
if (location.protocol === 'http:') {
  alert('HTTPS でアクセスしてください');
}
*/

document.getElementById('translateBtn').addEventListener('click', async () => {
  const src = document.getElementById('srcLang').value.trim();
  const tgt = document.getElementById('tgtLang').value.trim();
  const text = document.getElementById('input').value;

  if (!('Translator' in self)) {
    alert('このブラウザは Translator API をサポートしていません。Chrome 138 以降をご利用ください。');
    return;
  }

  try {
    status.textContent = '準備中…';
    const translator = await createTranslator(src, tgt);
    status.textContent = '翻訳中…';
    document.getElementById('output').value = await translator.translate(text);  // ③ 翻訳実行
    // translateLarge(text, translator); // 大量テキストはチャンク化して翻訳
    status.textContent = '完了';
  } catch (err) {
    console.error(err);
    alert(err.message);
    status.textContent = '';
  }
});

参照