CLI を一つインストールし、Cursor に一度プロンプトを送るだけで、英語オンリーの JSX が [locale] ルーティング・生成済みキー・プッシュごとの自動同期を備えた多言語対応アプリに変わります。globalize.now は AI 駆動のローカライゼーション基盤で、Cursor がやり残した i18n 作業――ハードコードされた文字列の抽出、next-intl キーとロケールファイルの生成、Git プッシュのたびに翻訳を同期し続けること――を代わりにこなします。以下の手順は標準的な App Router 構成のプロジェクトを前提としています。テストリポジトリでの実測時間は合計13分40秒でした。

Cursor が Next.js の UI を組み立てるとき、実際には何が壊れているのか?

Cursor は「動くUI」を作ることに最適化されていて、アーキテクチャの整合性までは考慮していません。自然言語の指示からコードを生成し、プロンプトを通じてコードの一部を更新する仕組みなので、JSX は人間がさっとプロトタイプを書くときのように出来上がります――文字列はインラインのまま、キーはなく、ロケールファイルもなく、[locale] の区切りすらありません。

Cursor が生成した典型的な Next.js のページはこんな感じです。

// app/page.tsx
export default function Home() {
  return (
    <main>
      <h1>Welcome to Acme</h1>
      <p>Get started in seconds.</p>
      <button>Sign up</button>
    </main>
  )
}

1ページに3つのハードコード文字列。実際のアプリでは数十のコンポーネントにまたがって何百も存在します。かつて Pages Router には i18n の設定が標準で組み込まれていましたが、App Router がデフォルトになった際に取り除かれ、開発者自身がミドルウェア、動的ルートセグメント、next-intl のような外部ライブラリを配線する必要が出てきました。Cursor のデフォルトの挙動は、こうした作業を何一つ肩代わりしてくれません。

その結果生まれるのが、Lovable アプリの翻訳がリリースのたびに壊れる理由 で取り上げたパターンです。コードベースが大きくなるにつれてハードコード文字列が積み重なり、「来月スペイン語を追加しよう」という話が、数週間がかりの大規模リファクタリングに化けてしまうのです。

Cursor プロジェクトに globalize.now をセットアップするには?

globalize.now でリポジトリを接続してください。最初の変換はアプリ内で一度だけ実行され、リポジトリを読み込んでハードコード文字列をキーに置き換え、あなたがレビューできるプルリクエストを開きます。それ以降のプッシュでは、新しく追加された部分だけが翻訳されます。

代わりに Cursor からこの最初の変換を実行したい場合は、プロジェクトのルートディレクトリで skills をインストールしてください。

npx skills add globalize-now/globalize-skills

CLI があなたのスタックを検出し、Cursor に適したプリセットを選び、プロジェクトにエージェントルールをインストールします。Next.js 16 の App Router プロジェクトでは、出力はこのようになります。

✓ Stack detected: Next.js 16 (App Router)
✓ Editor detected: Cursor
✓ Preset selected: globalize-guide + next-intl
✓ Installed 4 skill files to .cursor/rules/
Done in 1.2s

スキルファイルは既存の Cursor ルールと並んで配置されます。これらは Cursor のエージェントに、文字列抽出の方法、next-intl の慣習に沿ったキーの生成方法、[locale] ルートセグメントの配線方法を伝えます。何もマシンの外に送信されることはなく、あなたのコードがアップロードされることもありません。

Cursor の代わりに Claude Code や Codex を使っている場合、CLI はそれらのツール向けの同等のスキルファイルをインストールします。その後の流れはまったく同じです。

エージェントは Cursor のコードベースからハードコード文字列をどうやって抽出するのか?

Cursor のエージェントパネルを開き、次のプロンプトを一つ送ってください。

Set up i18n for this project. Use English, Spanish, German, and Arabic.

エージェントはインストール済みのルールを読み込み、app/ と components/ の各ディレクトリをスキャンして結果を報告します。12ページのマーケティングサイトの場合、報告は通常このようになります。

Detected Next.js 16 with App Router.
Found 47 hardcoded strings across 12 components.
Best fit: next-intl. RTL required for Arabic.

Plan:
- Install next-intl
- Move app/* into app/[locale]/*
- Generate i18n/request.ts and middleware.ts
- Extract 47 strings to messages/en.json
- Convert JSX to useTranslations / getTranslations calls

Proceed? (y/n)

エージェントがここでこなしているのは、next-intl のドキュメントが「面倒な部分」と呼ぶ作業です――ミドルウェア、動的ルートセグメント、リクエスト設定、そして翻訳フックを使うようコンポーネントを一つずつ変換していく作業です。あなたは計画を確認して承認するだけ。エージェントは変更をまとめて1つのマルチファイル編集として提示し、Cursor の差分ビューで承認・却下できます。

next-intl のキーとロケールファイルはどうやって生成されるのか?

計画を承認すると、エージェントは標準の next-intl レイアウトを生成します。リポジトリには次の4つが新たに加わります。

i18n/
  request.ts
  routing.ts
middleware.ts
messages/
  en.json
  es.json
  de.json
  ar.json
app/
  [locale]/
    layout.tsx
    page.tsx
    ...

messages/en.json の中では、抽出された47個の文字列が、コンポーネントやルートごとにグループ化された名前空間付きのキーになります。

{
  "Home": {
    "heading": "Welcome to Acme",
    "lede": "Get started in seconds.",
    "signupCta": "Sign up"
  }
}

元の page.tsx は書き換えられ、クライアントコンポーネントには useTranslations、サーバーコンポーネントには getTranslations が使われるようになります。この使い分けは自動で行われます。エージェントは各コンポーネントが "use client" ディレクティブを持っているかどうかを読み取り、適切なフックを選びます。

スペイン語、ドイツ語、アラビア語の JSON ファイルは、エージェントがあなたのコンポーネント名やプロパティ名から構築した用語集に沿った初回翻訳付きで生成されます。ブランド用語は英語のまま残ります。RTL への対応もレイアウトに組み込まれます――ロケールに応じて dir 属性が設定され、エージェントが検出できる範囲で、固定の left/right ユーティリティが CSS の論理プロパティに置き換えられます。

これは、AI エージェントが実際のモノレポを国際化するとどうなるか? で本番モノレポに対して実行したのとまったく同じエンドツーエンドのパターンです。手順の形式は同じで、違うのは入力だけです。

最初の実行後、Git プッシュ同期はどう機能するのか?

最初の実行は一度きり。同期はずっと続きます。

エージェントの作業が終わったら、ダッシュボードでリポジトリを globalize.now に接続します。それ以降は次のようになります。

Push to main
   ↓
globalize.now diffs against last synced state
   ↓
New hardcoded strings get extracted + keyed
   ↓
Translations generated for every configured locale
   ↓
PR opened with locale file updates

Cursor を開いておく必要はありません。Claude Code を動かし続ける必要もありません。同期は Git レイヤーで行われるため、どのツールが次のUIを書いたとしても問題なく機能します。来週 Cursor があるコンポーネントを再生成し、新しいボタンを3つ追加すれば、それらのボタンは翻訳済みの状態で次の PR に反映されます。

手作業でのエクスポートは不要です。レビュー待ちのキューもありません。CSV ファイルをやり取りする手間もありません。約束することは、globalize.now でアプリをグローバル化する方法 で紹介したのと同じです――一度セットアップすれば、あとはプッシュのたびに自動同期されます。

すでに手動で next-intl をセットアップしている場合はどうなる?

エージェントはまずそれを読み込みます。

i18n/request.ts が存在する場合、エージェントはあなたの設定を上書きせずに取り込みます。messages/en.json にすでに Pricing.heading がある場合は、新しく生成する代わりにそのキーを再利用します。あなたの名前空間の命名規則が Pricing.heading(パスカルケース、ネスト構造)ではなく pricing.heading(小文字、ドット区切り)であれば、エージェントはそれに合わせます。

エージェントが唯一頑なに拒むのは、既存のロケールファイルを黙って上書きすることです。キーの衝突が発生した場合は処理を止めて確認を求めます。この振る舞いは npx skills add globalize-now/globalize-skills によってインストールされるスキルルールに組み込まれており、あなたが設定する必要はありません。

globalize.now はこの問題を解決します。Next.js のリポジトリを接続すれば、変換はアプリ内で一度だけ実行され、そこから先のエディタ上の作業は npx skills add globalize-now/globalize-skills のスキルがカバーします。仕組みの詳細は globalize.now をご覧ください。

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

globalize.nowを無料で試す