translate-kit

codegen

Replace hardcoded strings with t() calls.

The codegen command transforms your source files by replacing hardcoded strings with t() calls (keys mode) or <T> components (inline mode), and injecting the necessary imports and hooks.

Usage

translate-kit codegen

Flags

FlagDescription
--dry-runPreview changes without writing files
--module-factoryConvert module-level constants into factory functions (experimental)

Prerequisites

Run scan first to generate the .translate-map.json file that codegen uses to map strings to keys.

Transformations

JSX Text Replacement

// Before
<h1>Welcome</h1>

// After
<h1>{t("common.welcome")}</h1>

Attribute Replacement

// Before
<input placeholder="Enter name" />

// After
<input placeholder={t("form.enterName")} />

Object Property Replacement

// Before
const item = { title: "Dashboard" };

// After
const item = { title: t("nav.dashboard") };

Import Injection

If missing, codegen adds the i18n import:

import { useTranslations } from "next-intl";

The import source is configured via scan.i18nImport (default: "next-intl").

Hook Injection

Codegen adds the useTranslations hook to components that use t():

function MyComponent() {
  const t = useTranslations();
  // ...
}

The hook is only injected in components that actually have t() calls.

Inline Mode

When mode is "inline", codegen uses <T> components instead of t() for JSX text:

JSX Text Wrapping

// Before
<h1>Welcome</h1>

// After
<h1><T id="hero.welcome">Welcome</T></h1>

Attribute Replacement

// Before
<input placeholder="Enter name" />

// After
<input placeholder={t("Enter name", "form.enterName")} />

The t() function in inline mode takes two arguments: the source text and the key.

Import Injection

Codegen detects whether a file is a client or server component:

  • Client files ("use client"): imports T and useT from the configured componentPath
  • Server files: imports T and createT from componentPath-server

Hook Injection

  • Client: const t = useT()
  • Server: const t = createT()

See the Inline Mode guide for full details.

Module Factory (experimental)

Warning: This feature is experimental and may change in future versions. Review the generated output before committing.

When you have translatable strings inside module-level constants (outside of React components), codegen normally skips them because there's no t() function available at module scope.

The --module-factory flag converts these constants into factory functions that receive the translator as a parameter:

// Before
export const footerLinks = [
  { title: "About", href: "/about" },
  { title: "Contact", href: "/contact" },
];

// After (with --module-factory)
export const footerLinks = t => ([
  { title: t("footer.about"), href: "/about" },
  { title: t("footer.contact"), href: "/contact" },
]);

Files that import these constants are automatically rewritten to call them with the component's translator:

// Before
import { footerLinks } from "./data";
export function Footer() {
  return <ul>{footerLinks.map(l => <li>{l.title}</li>)}</ul>;
}

// After
import { footerLinks } from "./data";
export function Footer() {
  const t = useTranslations("footer");
  return <ul>{footerLinks(t).map(l => <li>{l.title}</li>)}</ul>;
}

Safety guards

The transform is skipped when it would be unsafe:

  • Constants with TypeScript type annotations
  • Constants referenced outside of functions/components
  • Constants imported via namespace imports (import * as data)
  • Constants that are mutated (.push(), reassignment, etc.)

Usage

translate-kit codegen --module-factory
translate-kit run --module-factory