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.json

include

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',
}
FieldDefaultPurpose
out"messages/messages.d.ts"Path (relative to config file) where the .d.ts is written.
baseLocaledataset's base localeLocale 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:

  1. --token <value> flag passed to the command
  2. API18N_TOKEN environment variable
  3. ~/.api18n/credentials.json (written by api18n 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',
  },
});