[ Next.js ]

Wrap hardcoded strings for next-intl automatically

Point Polyglot at a Next.js App Router project and it converts hardcoded JSX text into next-intl calls — hooks injected, catalogs written, wiring verified.

1 Min. LesezeitAlle Frameworks

next-intl is the App Router's de-facto i18n library — and the tedious part of adopting it is never the library. It's the hundreds of hardcoded strings already in your JSX. Polyglot's wrap command finds every one with a real parser (tree-sitter, not regex), rewrites the call sites, and writes the catalog next-intl loads.

The transformation

Before — src/app/page.tsx
"use client";

export default function Page() {
    return (
        <main>
            <h1>Welcome back</h1>
            <p>Your projects are ready</p>
            <input placeholder="Search projects" />
        </main>
    );
}
After — src/app/page.tsx
"use client";
import { useTranslations } from "next-intl";

export default function Page() {
  const t = useTranslations("src.app.page");
    return (
        <main>
            <h1>{t('welcome_back')}</h1>
            <p>{t('your_projects_are_ready')}</p>
            <input placeholder={t('search_projects')} />
        </main>
    );
}

Text nodes become t() calls, attributes like placeholder become expressions, and the useTranslations hook is injected into each component that needs it — including the import.

Where the keys go

Keys are namespaced by file path and written to messages/en.json, the exact layout next-intl's getRequestConfig loads. Your target languages get their catalog files created alongside — empty on purpose, so next-intl's loader resolves immediately — and polyglot translate fills them.

Written — messages/en.json
{
  "src": {
    "app": {
      "page": {
        "search_projects": "Search projects",
        "welcome_back": "Welcome back",
        "your_projects_are_ready": "Your projects are ready"
      }
    }
  }
}
Translated — messages/de.json
{
  "src": {
    "app": {
      "page": {
        "search_projects": "Projekte suchen",
        "welcome_back": "Willkommen zurück",
        "your_projects_are_ready": "Ihre Projekte sind bereit"
      }
    }
  }
}
Translated — messages/fr.json
{
  "src": {
    "app": {
      "page": {
        "search_projects": "Rechercher des projets",
        "welcome_back": "Bon retour",
        "your_projects_are_ready": "Vos projets sont prêts"
      }
    }
  }
}

What makes this safe

  • Never breaks a build. Every transformed file is re-parsed before it's written; anything the parser can't prove safe is flagged for review instead of guessed at.
  • Server components respected. Client-only hooks are never injected into React Server Components — the App Router's sharpest i18n edge is handled for you.
  • Wiring verified. After writing, Polyglot checks that every injected import resolves, the runtime package is installed, and every key reads back from the catalog:
✓ 3 strings auto-wrapped · 0 flagged for manual review · 0 unsafe transforms → polyglot-i18n-report.md
✓ wiring checks passed (1 injected import(s), 3 catalog value(s), 1 catalog file(s))

From zero to translated

$ curl -fsSL https://getpolyglot.ai/install.sh | sh
$ polyglot init --framework nextjs
$ polyglot scan
$ polyglot wrap
$ polyglot translate --languages de   # 50 strings free, no signup

wrap and scan run entirely offline — the dry run shows every change before anything is written. Your first 50 translated strings are free, no signup.

Im Terminal starten

Schluss mit der Suche nach unübersetzten Strings.

Installieren Sie die CLI, führen Sie einen Scan durch und sehen Sie genau, was Ihnen fehlt. Kostenlos, kein Konto erforderlich.

$curl -fsSL https://getpolyglot.ai/install.sh | sh
Wrap hardcoded strings for next-intl automatically | Polyglot