Configuration

Where Configuration Lives

Kit policy — the things you tell the tool that it cannot see for itself — is declared in one of two files. Every field either of them accepts, with its type and its constraints, is in the configuration field reference.

The Two Files

WhereAppliesRequires
i18n-kit.config.tsImmediately, from the file on diskNothing beyond the CLI
.i18n-mcp.jsonImmediately, from the file on diskNothing beyond the CLI

Both accept the same field names and validate against one shared zod schema, with a type-level guard that fails the CLI build if the schema and the documented config type drift apart.

Policy is not declared in nuxt.config.ts. @the-i18n-kit/nuxt publishes what Nuxt already resolved — the layer graph and the locale table — so you do not restate those by hand. It carries no glossary, no protected locales and no scan rules. See declared versus derived.

i18n-kit.config.ts

A TypeScript file that exports its config as the default export:

i18n-kit.config.ts
import { defineI18nKitConfig } from '@the-i18n-kit/cli/config'

export default defineI18nKitConfig({
  context: 'A B2B booking platform.',
  glossary: { anny: 'Brand name. NEVER translate.' },
  protectedLocales: ['de-formal'],
})

defineI18nKitConfig returns its argument unchanged. Its entire job is the type: protectedLocales autocompletes, and a misspelled protectedLocals is a red squiggle while you write it rather than a failed command later.

Five other extensions are accepted, so a JavaScript project does not have to adopt TypeScript to get a checked config: .mts, .js, .mjs, .cjs and .cts. If a directory contains more than one, the CLI uses the first in that order — .ts first — and warns, naming the files it ignored.

Import @the-i18n-kit/cli/config. The CLI aliases that specifier to the copy of defineI18nKitConfig already running, so a config written against these docs loads even under a bare npx in a project that never installed the package. The pre-rename spelling the-i18n-cli/config resolves the same way, and keeps working until the deprecation window closes.

.i18n-mcp.json

The original format, still supported and still what the-i18n-cli init writes. It accepts the same keys, plus a $schema pointer for editor completion:

.i18n-mcp.json
{
  "$schema": "node_modules/@the-i18n-kit/mcp/schema.json",
  "context": "A B2B booking platform.",
  "glossary": { "anny": "Brand name. NEVER translate." },
  "protectedLocales": ["de-formal"]
}

How Each One Reaches a Command

Both files are read directly from disk. Every adapter funnels through one loader, loadProjectConfig, which searches from the project directory upward for the nearest i18n-kit.config.* and the nearest .i18n-mcp.json — the way ESLint, Prettier and tsconfig.json resolve theirs. The search stops at the first directory that has one, so a config in an app directory shadows one at the repository root rather than merging with it.

The CLI never loads your Nuxt config to read policy out of it. What @the-i18n-kit/nuxt writes to .nuxt/i18n-kit.json during a build is the layer graph and the locale table — facts Nuxt resolved that would otherwise have to be restated by hand. Policy is not in there.

Because both files are read straight from disk, the policy in them applies to the first command run in a checkout that has built nothing — which is what a CI job that runs the kit before the build, or a container with only the repository mounted, is. That matters most for the two keys that suppress work: protectedLocales, which excludes locales from automatic translation, and orphanScan, which narrows what counts as an orphan key.

Choosing

  • Start with i18n-kit.config.ts. It is checked by your editor, needs no build, and works on every framework the kit supports.
  • Keep .i18n-mcp.json if you already have one and it is doing its job, or if something other than a person generates it. There is no deadline to migrate, and init still writes this format.
  • Install @the-i18n-kit/nuxt alongside either file if you are on Nuxt. It does not hold policy; it removes the need to restate the locales and layers Nuxt already knows about.

You can use more than one. What you cannot do is declare the same key in two of them: that is an error naming both, not a merge. See precedence and conflicts.

Limits

  • The kit does not read package.json, .env, or a config/ directory for its own settings. Provider credentials are the exception: an API key comes from the --apiKey flag or a provider environment variable such as OPENAI_API_KEY, never from a config file that could be committed.
  • Neither file supports extending, importing or composing another kit config. The nearest one wins outright.
  • .i18n-mcp.json keeps its name for compatibility even though the CLI reads it too, not only the MCP server.
Copyright © 2026