Configuration
The api18n.config.ts file — every field, every default.
The CLI loads api18n.config.ts (or .js, .mjs) from the current
working directory. It must export a default object built with
defineConfig — that gives you TypeScript autocomplete on every field.
// api18n.config.ts
import { defineConfig } from '@api18n/cli';
export default defineConfig({
locales: 'messages/{locale}.json',
});Every field is optional. The shape:
interface UserConfig {
locales?: string;
include?: string[];
baseUrl?: string;
companyId?: string;
typegen?: boolean | { out?: string; baseLocale?: string };
}locales
Type: string · Default: "messages/{locale}.json"
Path pattern (relative to the config file) where local translation JSON
files live. The {locale} placeholder is replaced with each language code
at pull/push time.
Examples:
locales: 'messages/{locale}.json';
// → messages/en.json, messages/pt-BR.json, messages/de.json
locales: 'src/i18n/{locale}/common.json';
// → src/i18n/en/common.json, src/i18n/pt-BR/common.jsoninclude
Type: string[] · Default: all locales enabled in the dashboard
Restrict pull/push to a subset of locales.
include: ['en', 'pt-BR'];If your dashboard has en, pt-BR, de, fr, and include is set to
['en', 'pt-BR'], the CLI only writes those two files locally. Useful
when a project ships in fewer languages than the rest of the company.
baseUrl
Type: string · Default: "https://www.api18n.com"
Override the dashboard URL. Set this for self-hosted instances or local
development against http://localhost:3000.
baseUrl: process.env.API18N_BASE_URL ?? 'https://www.api18n.com';companyId
Type: string · Default: auto-resolved if you belong to one company
If your user belongs to multiple companies, the CLI returns HTTP 409 with the list. Pin a specific company to skip the ambiguity:
companyId: process.env.API18N_COMPANY_ID;Personal Access Tokens can also be scoped to a single company at creation
time — if your PAT is scoped, companyId in the config is redundant.
typegen
Type: boolean | TypegenConfig · Default: true
Controls the messages.d.ts file written alongside the JSON. Set to
false to disable type generation:
typegen: false;Or provide an object to customize:
typegen: {
out: 'src/types/messages.d.ts',
baseLocale: 'pt-BR',
}| Field | Default | Purpose |
|---|---|---|
out | "messages/messages.d.ts" | Path (relative to config file) where the .d.ts is written. |
baseLocale | dataset's base locale | Locale used to infer argument types per key (default: en). |
The base locale matters because the CLI parses each message string to
infer arg types. Hello {name} becomes { __raw: 'Hello {name}'; name: string | number }. Plurals ({count, plural, …}) infer number, dates
infer Date | number, tags infer (chunks: ReactNode) => ReactNode.
Token resolution order
The CLI looks for the auth token in this order — first match wins:
--token <value>flag passed to the commandAPI18N_TOKENenvironment variable~/.api18n/credentials.json(written byapi18n login)
Setting API18N_TOKEN in CI is the standard pattern. There's no token
field in api18n.config.ts — config files get committed and secrets
shouldn't.
Full example
// api18n.config.ts
import { defineConfig } from '@api18n/cli';
export default defineConfig({
locales: 'src/messages/{locale}.json',
include: ['en', 'pt-BR', 'de'],
baseUrl: process.env.API18N_BASE_URL ?? 'https://www.api18n.com',
companyId: process.env.API18N_COMPANY_ID,
typegen: {
out: 'src/types/messages.d.ts',
baseLocale: 'en',
},
});