GA4が教えてくれた。海外の人がアクセスしている
LOG138HRI2026/4/10

GA4が教えてくれた。海外の人がアクセスしている

シミュレーションでも実機でもなく、GA4のリアルタイムデータを眺めるところから始まった。

💡 Key Takeaway

「ブラウザ翻訳で記事は読める。足りないのはチャットの英語対応だった。」GA4の北米流入をきっかけに、AIエージェントのEN/JA切り替えを実装した。記事コンテンツに手をつけず、チャットUI1本で海外ユーザーへの導線を整えた。

やったこと

起きたこと

判断

GA4のリアルタイムを確認した

北米から28ユーザー、first_visit 27件という流入を発見

英語対応を今日やる理由ができた

DifyにEN/JA変数を追加した

language変数をワークフローの開始ノードに追加

プロンプト1行の変更だけで対応できた

チャットUIにENボタンを実装した

押すと挨拶・サジェスト・プレースホルダーが英語に切り替わる

Dify変数よりクエリプレフィックスの方が確実だった

TOPページの案内テキストを英語化した

「Chat with Hakobu — EN / JA available」に変更

日本語ページのまま、導線だけ英語にする判断

北米から、人が来ていた

— ログを眺めていたら、想定外のデータが出てきた。

GA4のリアルタイム画面を開いたら、過去30分のアクティブユーザーが28人。地図を見ると、北米に大きな青い点が集まっていた。first_visitが27件。ほぼ全員が初見の訪問者だ。

上位ページは「Record | 記録 シミュレーション」「Record | 記録 グリッパー」——技術ログを直接読みに来ている。おそらく海外のエンジニアか研究者だ。

「ブラウザ翻訳で読んでいるはず」と思った。自分もそうしているから、その判断は正しいと思う。記事コンテンツを英語化するコストをかけなくていい。でも、チャットが日本語のまま返してくるのは問題だ。

以前、チャットUIに言語切り替えボタンを実装しようとして、うまく動かなかったことがあった。Difyからの返答が日本語のまま帰ってくる問題だった。改めてその仕組みを作り直した。

Dify側の変更——変数を1つ追加するだけ

ワークフローの開始ノードに language という変数を追加した。

変数名: language
タイプ: String
デフォルト値: 日本語
非表示: ON(ユーザーには見せない)

LLMノードのシステムプロンプトに1行追加した。

- 必ず {{language}} で回答すること

そして、フォローアップ提案のマーカーが言語で変わってしまう問題を防ぐために:

- フォローアップ提案のマーカーは言語に関わらず必ず [次の質問] を使うこと

Difyを公開して、次はHTML側の実装に入った。

チャットUI側の実装

最初の試み——Dify変数に渡す方式

最初は、APIコールの inputs にlanguage変数を渡す方式を試みた。

inputs: { language: ptmLang },

でも、Difyのチャットフローは会話開始時にしかinputsを参照しない。会話途中で言語を切り替えてもうまく動かなかった。

解決策——クエリプレフィックス方式

より確実な方法に切り替えた。クエリ自体に言語指示を埋め込む。

query: ptmLang === 'English' ? '[Respond in English] ' + input : input,

英語モードのとき、ユーザーの質問の先頭に [Respond in English] を自動付与する。Difyの変数設定に依存しないので、毎回確実に動く。

ENボタンの実装

ヘッダーに切り替えボタンを追加した。

<div id="ptm-header-right">
  <span id="ptm-header-sub">Pixels to Motors AI</span>
  <button id="ptm-lang-btn" onclick="ptmToggleLang()">EN</button>
</div>

ボタンのスタイルは白背景・黒テキスト。ホバーでブランドカラーのイエローに変わる。

#ptm-lang-btn {
  background: #ffffff;
  border: 1px solid #ffffff;
  color: #0a0a0a;
  font-family: 'Syne', sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  padding: 4px 10px;
  cursor: pointer;
  border-radius: 2px;
  transition: all .2s;
}
#ptm-lang-btn:hover { background: #e8ff00; border-color: #e8ff00; color: #0a0a0a; }

切り替え関数——チャットごとリセットする

ボタンを押したとき、単に言語フラグを変えるだけでは不十分だった。それまでの会話が日本語で表示されたまま残るから、画面が混在してしまう。

切り替えのタイミングでチャット全体をリセットし、言語に合った挨拶とサジェストを表示し直す設計にした。

function ptmToggleLang() {
  ptmLang = ptmLang === '日本語' ? 'English' : '日本語';
  const btn = document.getElementById('ptm-lang-btn');
  btn.textContent = ptmLang === '日本語' ? 'EN' : 'JA';
  document.getElementById('ptm-input').placeholder =
    ptmLang === '日本語' ? 'ロボットのことを聞いてみよう' : 'Ask me anything about the project';
  ptmConvId = '';

  // チャットをリセットして言語に合った挨拶を表示
  const box = document.getElementById('ptm-messages');
  box.innerHTML = '';
  if (ptmLang === '日本語') {
    ptmAppendMsg('ai', 'ハコブくんにまかせて!\nロボット開発の記録、全部頭に入ってるよ。\nなんでも聞いてね!');
    ptmAppendSuggestions([
      'このプロジェクトって何をやってるの?',
      '一番苦労したのはどこ?',
      'デジタルツインって何?'
    ]);
  } else {
    ptmAppendMsg('ai', "Hi! I'm Hakobu, your guide to the Pixels to Motors project.\nAsk me anything about the build log, the robot arm, or the R2R2R pipeline!");
    ptmAppendSuggestions([
      'What is this project about?',
      'How does the simulation connect to the real robot?',
      'Why use an iPhone for robotics?'
    ]);
  }
}

ptmConvId = '' でDify側の会話IDもリセットする。次のメッセージは新しい会話として送られるので、inputsも新鮮な状態で渡せる。

動作確認

ENを押すと:

  • ハコブくんの挨拶が英語に切り替わる

  • サジェストボタンが英語3択に変わる

  • プレースホルダーが「Ask me anything about the project」になる

  • 以降の返答がすべて英語で返ってくる

JAに戻すと、チャットがリセットされて日本語の挨拶に戻る。

TOPページの導線も英語化

チャットだけ英語対応しても、そこへ誘導する導線が日本語のままでは気づいてもらえない。

TOPページのキャプションを変更した。

変更前: Pixels to MotorsのAIエージェントはこちら!
変更後: Chat with Hakobu, the AI guide to this project — EN / JA available →

ハコブくんの吹き出しも英語に変更。シンプルな英語なので、日本語話者にも読める。

判断したこと

記事コンテンツを英語に翻訳することはやらなかった。

海外ユーザーはブラウザ翻訳で読んでいる。それで実際に読めているなら、そこにコストをかける必要はない。足りていなかったのはチャットの英語対応だけだった。

チャット1本を直す。TOPの導線テキストを変える。それだけで、今日のGA4の28人に対して「ここで英語で話せる」という導線を作れた。

精度より体験の成立を優先する——という設計哲学は、ロボット開発だけじゃなく、こういうところにも出てくる。

※ プロジェクト名「R2R2R」は、UC Berkeley・Toyota Research Instituteの研究「Real2Render2Real」(Yu, Fu et al., 2025)の概念に触発されています。現実空間をデジタルツイン化し、仮想空間での試行から得た知見を実世界のモーター駆動へ還元する——その設計と実装過程を毎日記録しています。技術アプローチおよび目的は独自のものです。