Polyglot emits formatMessage({ id, defaultMessage }) — self-contained calls that render correctly even before your extraction pipeline runs.
react-intl is an extraction-pipeline ecosystem: catalogs are generated from source by formatjs extract. So the correct wrap isn't a bare ID — it's a self-contained call that carries the text:
"use client";
export default function Page() {
return (
<main>
<h1>Welcome back</h1>
<p>Your projects are ready</p>
<input placeholder="Search projects" />
</main>
);
}"use client";
import { useIntl } from "react-intl";
export default function Page() {
const intl = useIntl();
return (
<main>
<h1>{intl.formatMessage({ id: "src.app.page.welcome_back", defaultMessage: "Welcome back" })}</h1>
<p>{intl.formatMessage({ id: "src.app.page.your_projects_are_ready", defaultMessage: "Your projects are ready" })}</p>
<input placeholder={intl.formatMessage({ id: "src.app.page.search_projects", defaultMessage: "Search projects" })} />
</main>
);
}Every call includes defaultMessage. That means:
IntlProvider has no entry for the new ID yet. No raw IDs in production, ever.formatjs extract collects it — your existing pipeline keeps working; Polyglot's calls are exactly what a careful react-intl developer writes by hand.useIntl() is injected into each component that needs it (client components only — server components are protected), and the catalog is written alongside:
{
"src.app.page.search_projects": "Search projects",
"src.app.page.welcome_back": "Welcome back",
"src.app.page.your_projects_are_ready": "Your projects are ready"
}{
"src.app.page.search_projects": "Projekte suchen",
"src.app.page.welcome_back": "Willkommen zurück",
"src.app.page.your_projects_are_ready": "Ihre Projekte sind bereit"
}{
"src.app.page.search_projects": "Rechercher des projets",
"src.app.page.welcome_back": "Bon retour",
"src.app.page.your_projects_are_ready": "Vos projets sont prêts"
}$ curl -fsSL https://getpolyglot.ai/install.sh | bash
$ polyglot init --framework nextjs
$ polyglot scan
$ polyglot wrap
$ polyglot translate --languages de # 50 strings free, no signupStart in your terminal
Install the CLI, run a scan, and see exactly what you're missing. Free, no account required.