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
| Where | Applies | Requires |
|---|---|---|
i18n-kit.config.ts | Immediately, from the file on disk | Nothing beyond the CLI |
.i18n-mcp.json | Immediately, from the file on disk | Nothing 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.
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:
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.
@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:
{
"$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.jsonif 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, andinitstill writes this format. - Install
@the-i18n-kit/nuxtalongside 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 aconfig/directory for its own settings. Provider credentials are the exception: an API key comes from the--apiKeyflag or a provider environment variable such asOPENAI_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.jsonkeeps its name for compatibility even though the CLI reads it too, not only the MCP server.