Replitアプリを多言語対応にするには、そのGitリポジトリをGitHubに接続し、翻訳カタログをそのリポジトリ内にコミットされたファイルとして管理し続けます。Replitはすでに、Agentのすべてのチェックポイントをコミットとして保存しているため、言語対応を考える前からリポジトリはすでに存在しています。必要な作業は、それをGitHubに乗せ、同じ履歴を通じてカタログが戻ってくるようにすることです。globalize.nowはAI駆動のローカリゼーションインフラであり、キーとロケールファイルを生成し、あなたのアプリがすでに使っているランタイムライブラリがそれを配信します。ランタイムの経路にダッシュボードが介在することはなく、ページ読み込み後に何かが翻訳されることもありません。

なぜAgentにアプリの翻訳を依頼しても、うまくいかないのでしょうか?

翻訳対象となるものがそもそも存在しないからです。Replit Agentにダッシュボードの作成を依頼すると、<h2>Your bookings</h2>はコンポーネントの中に直接書き込まれ、カタログを参照する仕組みにはなりません。見出し、ボタン、空状態、トースト通知、バリデーションエラー――そのすべてが、プロンプトで使った言語のリテラル文字列としてJSXに埋め込まれます。

そのため、後から「アプリをアフリカーンス語に翻訳して」とAgentに依頼しても、得られる結果は中途半端な二択になります。テキストを差し替えただけのコンポーネントの複製が作られるか、Agentがたまたま目にした画面だけをカバーする手作りのtranslationsオブジェクトが作られるか、のどちらかです。どちらもロケール層とは呼べません。次に追加する機能は、結局また英語のままリリースされます。同じ現象はCursorが繰り返しハードコードされた文字列を追加する問題でも取り上げましたが、Replit Agentも変わりません。目の前のプロンプトを解決しているだけで、その裏にあるアーキテクチャの問題には手をつけていないからです。

解決策は構造そのものを変えることです。文字列にキーを与え、翻訳をファイルに格納し、実行時にそのファイルを参照するようにする――これがコードベースにおける「多言語対応」の意味であり、一度きりの変更です。

Replit Agentは実際には何を生成しているのか?

一般的なWebプロジェクトです。これは朗報と言えます。Replitが用意しているアプリタイプは、フロントエンドにReactとShadCN UIを組み合わせ、多くの場合同じプロジェクト内にExpressサーバーを併設する構成で、すべてTypeScriptで書かれています。2025年9月以降、Agentは持ち込んだ任意のフレームワーク(GitHubからインポートしたリポジトリを含む)にも対応するようになったため、Next.jsやVueのプロジェクトも可能ですが、デフォルトの構成は依然としてReactスタックです。

ローカライゼーションの観点で重要なのはスタックのみで、これは標準的な領域です。React+Vite+TypeScriptはi18nエコシステムの中で最もサポートが手厚い組み合わせで、i18next、Lingui、react-intlはいずれもこの構成を直接ターゲットにしています。仮にAgentがNext.jsアプリを生成した場合は、next-intl、react-i18next、Linguiのいずれかを選ぶことになりますが、その比較は別の記事で扱っています。

フロントエンドのみのビルダーと異なるのは、プロジェクトの後半部分です。Replitアプリには通常サーバーがあり、サーバーにも文字列が存在します。この点については後述します。

Replitアプリの中に、Gitリポジトリはどこにあるのか?

実はもうそこにあります。Replitのバージョン管理は内部的にGitで動いており、Agentのチェックポイントはそのリポジトリ内のコミットに当たります。Agentが機能を完成させてロールバックポイントを提示するたび、実際にはコミットが行われているのです。Replit自身のドキュメントでも、外部リポジトリと連携する場合――まさに今回のケース――は、長期的な追跡のために通常のGitコミットに切り替えることを推奨しています。

これをGitHubに反映させる手順は次のとおりです。

  1. プロジェクトエディタの「ツール」セクションからGitツールを追加します。
  2. 「連携サービス」からGitHubアカウントを接続し、Gitパネルからリポジトリを接続します。プロジェクトがまだ初期化されていない場合は、パネルが先にその初期化を提案してくれます。
  3. プッシュします。パネルはワンクリックでプッシュを実行し、Shell上で行った操作とも同期されるため、git push origin mainも問題なく機能します。

ReplitはGitLabやBitbucketにも対応しており、流れは同じです。重要なのはどのプロバイダーを使うかではなく、リポジトリがローカライゼーションのジョブからプルリクエストを開ける場所に置かれるという点です。

文字列に手を付ける前に、まずこれを済ませておきましょう。ローカライゼーション作業はファイル単位の作業であり、diffこそがレビューに最適な場所です。

Replitアプリにとって「ダッシュボードなし」とはどういう意味か?

翻訳された文字列がリポジトリ内のファイルとして存在し、アプリが他のアセットと同じようにそれらを配信するという意味です。scriptタグも、ページ読み込み時の外部フェッチも、訪問者とコンテンツの間に立つベンダーアカウントも必要ありません。

代替手段として、ページの描画後にテキストを差し替えるランタイム型のウィジェットがあります。しかしこれには構造的なコストがつきものです。最初の表示は英語のままで、クローラーが最初に読むHTMLには翻訳済みのコンテンツが含まれず、サードパーティのスクリプトが本番環境の経路に割り込み、さらに文字列はベンダーのストアに保管されるため、乗り換える際にはエクスポート作業が必要になります。この議論のLovable版はダッシュボードなしでLovableアプリをローカライズするにあり、そのままReplitにも当てはまります。

ここでReplit特有の理由がひとつあり、それがより重要になります。Replitはアプリのデプロイを代行してくれるため、あなたのReplitドメイン上で動いているのは、デプロイ時点でプロジェクトに含まれていたものそのものです。ウィジェットは、外部からそのデプロイを翻訳することになります。一方、リポジトリ内にカタログがあれば、デプロイの時点ですでにすべての言語が含まれており、Replitのプレビューでは公開前にドイツ語版を確認できます。

ここには実際のトレードオフがあり、正直に述べておく価値があります。コピーの変更にはコミットと再デプロイが必要で、保存ボタンひとつで済むわけではありません。Replitから一人で開発・リリースしている人にとってはさほど問題になりませんが、プロジェクトに手を触れずに公開中のコピーをその場で編集したい人にとっては制約になります。

リポジトリ起点のセットアップはどう機能するのか?

globalize.nowアプリでリポジトリを接続します。変換処理はコードベースに対して一度だけ実行され、ハードコードされた文字列はキー付きのカタログユニットへと変換され、コンポーネントはリテラルを保持する代わりにランタイムライブラリから読み込むようになります。これは一度きりの操作であり、後から繰り返し実行されるものではありません。

変換完了後は、アプリの成長に合わせてプッシュジョブが新しいカタログユニットを翻訳していきます。Agentに新しい設定ページを依頼し、プッシュすれば、新しいユニットは翻訳され、既存のユニットはそのまま維持されます。カタログは、ランタイムライブラリに応じてJSONまたはPO形式のコミット済みファイルとしてプルリクエスト内に戻ってきて、他の変更と同様にレビューできます。

境界線は2つあり、それはこのカテゴリがよく混同されるためです。globalize.nowはランタイムライブラリを置き換えるものではなく、i18next、Lingui、next-intlはそのまま役割を果たし続けます。また、DeepLと競合する翻訳エンジンでもありません。globalize.nowは、その間に位置してキーとロケールファイルを生成する層です。仕組みの詳細は開発者向け概要をご覧ください。

翻訳結果はどうやってReplitに戻ってくるのか?

同じGitパネルを使い、逆方向に取り込みます。この点がBoltやLovableと異なる部分で、Replitはアプリの実行環境でもあるためです。

  1. GitHub上でプルリクエストをレビューし、マージします。
  2. ReplitのGitパネルでPullを選択します。もしその間にあなた自身やAgentが同じファイルを変更していた場合は、パネルが競合箇所をハイライトしてくれるので、マージを完了する前にエディタ上で解決してください。
  3. 再デプロイします。これでカタログがプロジェクトの一部となり、デプロイにはすべての言語が含まれるようになります。

Replit特有の注意点がひとつあります。Agentのチェックポイントは、ファイルを含むプロジェクト全体の状態を復元します。翻訳ブランチをプルする前に作成されたチェックポイントまでロールバックすると、カタログも一緒に失われてしまいます。マージを一つの節目として扱い、その直後にAgentにチェックポイントを作成させ、ロールバックする際はそれより前のものではなく、そのチェックポイントに戻すようにしましょう。

サーバー側に存在する文字列とは?

フロントエンドがJSXとして目にすることのない文字列です。Expressバックエンドを持つReplitアプリには、もうひとつの文字列の領域があります。APIのエラーメッセージ、バリデーション応答、メールの件名、通知本文、CSVのヘッダーなど、サーバーが送信前にフォーマットするあらゆるものです。フロントエンドのカタログはそこには届かず、ウィジェットに至ってはDOMに現れないため、そもそも認識すらできません。

パターン自体はクライアント側と同じで、それをサーバー側に適用するだけです。サーバーにもランタイムライブラリの複製を持たせ、リクエストから訪問者のロケールを読み取り(Accept-Languageヘッダーやユーザーレコード上のロケールフィールドなど)、文字列リテラルではなくカタログから応答をフォーマットします。キーの名前空間は共有されるため、errors.booking.overlapはトースト通知でも409レスポンスでも同じ意味を保ちます。

これを省略すると、アプリは最初のエラーが出るまでは多言語対応に見えても、その瞬間に英語で話し始めてしまいます。

2つ目の言語を追加する前に確認すべきことは?

変換の前にこれらを確認しておきましょう。どの項目も、5つの言語が同時進行になってからより、今のうちに直すほうがずっと安く済みます。

  • 連結された文字列。 "Welcome back, " + user.nameは翻訳者が語順を入れ替えることができません。代わりに埋め込み(補間)を使いましょう。
  • 複数形。 英語には2つの形しかありませんが、ポーランド語には3つ、アラビア語には6つの形があります。count === 1に対する三項演算子は、ほとんどの言語で誤りになります。
  • 日付、数値、通貨。 クライアント側でもサーバー側でも、文字列フォーマットではなくIntlを使用してください。
  • レイアウト。 ドイツ語やフィンランド語は英語より文字数が長くなりがちです。固定幅のボタンは崩れ、Tailwindのクラスも実際のテキストが入るまでは問題なく見えてしまいます。
  • 右から左(RTL)への対応。 アラビア語やヘブライ語をロードマップに含める予定があるなら、今のうちに決めておきましょう。RTL対応は後から追加するとコストが高くつきます。
  • カタログのずれ。 カタログが存在するようになると、一部のロケールにだけキーが追加されて他には反映されない、という静かなバグが起こり得ます。翻訳ファイルが同期からずれていく理由では、そのメカニズムとプッシュジョブによる対処方法を解説しています。

料金はワークスペース単位で、シート課金も言語数に応じた課金もありません。そのため、対応言語の数は予算の制約ではなく、あくまでプロダクト側の判断事項になります。最新の料金は料金ページをご覧ください。他のAIビルダーについても同様の手順を知りたい場合は、vibe codersの概要記事が出発点になります。

どこから始めるか

すでにReplitプロジェクトがGitHubに接続済みなら、次のステップはツール選定ではなく、そのリポジトリに対する変換処理です。まだ接続していない場合は、Gitパネルの設定がその前段階になります。

globalize.nowは、ハードコードされたアプリ内テキストを翻訳可能なロケールファイルに変換し、リリースのたびに自動で最新の状態を保ちます。

globalize.nowを無料で試す