Use when extracting user-facing strings, moving literals into `_locales/en-US.ts`, and rewriting source to `t(...)`, `Trans`, or `dt(...)` translation keys.
This skill is user-invoked only. Run it only when the user explicitly invokes /i18n-extract.
Extract user-facing strings from source files into locale files, then update the source to use translation keys.
This workflow updates en-US.ts only unless the user explicitly asks to update other locales too.
/i18n-extract [file_or_directory] [options]
Required input:
src/Optional input:
Defaults:
en-US.ts onlyMain app:
src/entrypoints/_locales/{locale}.ts"common"Plugins:
src/plugins/{plugin-path}/_locales/{locale}.tsnamespace constant from src/plugins/{plugin-path}/_locales/index.tsen-US Locale File Formatimport type { LanguageMessages } from "@complexity/i18n";
export default {
keyName: "Simple string",
nested: {
key: "Nested value",
withParam: "Hello {name}",
withComponent: "Click <0>here</0> to continue",
},
} as const satisfies LanguageMessages;
Non-English locale files are a separate follow-up step and typically mirror the same shape using the local Translations type from _locales/index.ts.
Inspect files in this order. Do not guess before checking.
_locales/index.tsen-US.tst or Trans - globally available (auto-imported)en-US first - English is source of truth_locales/index.tsnamespace.section.keyt(...) for plain textTrans when the translated string contains component placeholders like <0>...</0>{name} / {count:number} / {date} style placeholdersaria-label, alt, and DOM title attributestitle, label, description, placeholder, message, content may be visible UI text depending on the componentdialog.confirm.title, filters.sort.newest, buttons.save.Extract visible user-facing strings from:
label, description, placeholder, message, content, textSkip:
aria-label, alt, and DOM title attributest(...) or TransChoose the smallest correct mechanism:
| Case | Locale entry | Source rewrite |
|---|---|---|
| Static text | plain string | t(...) |
| Simple placeholders | plain string with {name} | t(..., { name }) |
| Number/date/list formatting | plain string with {count:number}, {date:date}, {items:list} | t(..., values) |
| Plural grammar | dt(...) with {count:plural} rules | t(..., { count }) |
| Enum-dependent wording | dt(...) with {name:enum} rules | t(..., { name }) |
| Embedded JSX/components | string with <0>...</0> placeholders | <Trans ... /> |
{name}{count:number}, {date:date}, {items:list}dt(...) forplural variationsenum variationsdt(...) for{name} interpolation{count:number} / {date:date} / {items:list} formattingTrans<Button>Save</Button>
Becomes something like:
<Button>{t("common.buttons.save")}</Button>
`Expires ${date}`
Becomes locale text like: