Documentation

React + Vite internationalization

Keep ordinary JSX in your components. Hedgeling's Vite plugin wraps supported user-facing strings during the build; the runtime selects translated text from the generated bundle.

1. Install with package access

Use Node.js 20 or later and a Hedgeling seat token, shown when you create a workspace and under Package seats in the console. Point the @hedgeling scope at Hedgeling's registry in your project's .npmrc, with the token in the HEDGELING_TOKEN environment variable. This guide assumes an existing React + Vite application with TypeScript and the React Vite plugin.

# .npmrc
@hedgeling:registry=https://platform.thehedgeling.com/registry/
//platform.thehedgeling.com/registry/:_authToken=${HEDGELING_TOKEN}
npm install @hedgeling/i18n

Yarn 1 and pnpm 9 use the same two lines. pnpm 10 and later do not read a token from a project's .npmrc: keep the first line there and run pnpm config set "//platform.thehedgeling.com/registry/:_authToken" "$HEDGELING_TOKEN" once. Yarn 2 and later use .yarnrc.yml instead, with an npmScopes entry for hedgeling that sets npmRegistryServer, npmAuthToken and npmAlwaysAuth.

If npm reports an authorization error, check that HEDGELING_TOKEN is set and that the seat is active. Do not paste a seat token into application source.

2. Configure extraction

Create .hedgeling/extract.config.json in the application root. Keep generated public assets outside the source scan.

{
  "sourceLocale": "en-US",
  "locales": ["fr-FR", "de-DE"],
  "scanRoots": ["src"],
  "outputDir": "public/i18n",
  "runtimeOutputDir": "public"
}

3. Add the Vite plugin

In vite.config.ts, keep the React plugin and add Hedgeling. Hedgeling's transform runs before JSX compilation.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { hedgelingI18n } from "@hedgeling/i18n/vite";

export default defineConfig({
  plugins: [hedgelingI18n(), react()],
});

4. Configure the runtime and language selector

Wrap the application entry in HedgelingProvider. Declare the source and supported locales explicitly.

import { createRoot } from "react-dom/client";
import { HedgelingProvider, useTranslation } from "@hedgeling/i18n/runtime";
import { App } from "./App";

function LanguagePicker() {
  const { locale, setLocale } = useTranslation();
  return <label>Language
    <select value={locale} onChange={event => setLocale(event.target.value)}>
      <option value="en-US">English</option>
      <option value="fr-FR">Français</option>
      <option value="de-DE">Deutsch</option>
    </select>
  </label>;
}

createRoot(document.getElementById("root")!).render(
  <HedgelingProvider sourceLocale="en-US" supportedLocales={["en-US", "fr-FR", "de-DE"]}>
    <LanguagePicker />
    <App />
  </HedgelingProvider>
);

5. Generate and verify artifacts

npx hedgeling extract --write
npx hedgeling translate --no-mt
npx hedgeling check
npm run build

This first pass creates the catalog and runtime artifacts without requesting machine translation. Source-language fallback is expected until translations exist. Configure a provider and run npx hedgeling translate when ready to send the selected content for translation; provider usage may incur costs. Review the generated changes before delivery.

The default runtime requests /hedgeling-bundle.json and /hedgeling-source-key-map.json. Serve them from the generated public directory. Applications deployed under a subpath should set the provider's bundle and key-map URLs to match that deployment.

Troubleshooting

  • If text stays in English, verify that the bundle contains the target translations and that both runtime files return JSON, not an HTML fallback.
  • If a provider is mounted but no strings are wrapped, check the Vite plugin and extraction scan roots. A language selector alone does not perform extraction.
  • Review diagnostics for text that requires explicit handling, including strings that serve both UI and program logic.
  • For search-facing pages, generate translated HTML at stable language URLs. Browser-side locale switching alone does not make each language independently discoverable.

Agent workflow and command effects · Markdown version