---
title: "Internationalization"
description: "Movk Nuxt Docs ships built-in multilingual support powered by @nuxtjs/i18n with an opt-in design. Without configuration it runs single-language; once configured it enables localized routing, per-locale content collections, a language switcher, and multilingual SEO."
canonical_url: "https://docs.mhaibaraai.cn/en/docs/getting-started/i18n"
---
# Internationalization

> Movk Nuxt Docs ships built-in multilingual support powered by @nuxtjs/i18n with an opt-in design. Without configuration it runs single-language; once configured it enables localized routing, per-locale content collections, a language switcher, and multilingual SEO.

## Overview

Internationalization is powered by [@nuxtjs/i18n](https://i18n.nuxtjs.org) with an **opt-in** design:

- **Disabled** — The layer only lists `@nuxtjs/i18n` as a dependency. The site runs single-language, UI strings come from the built-in translations, and routes are not localized.
- **Enabled** — Once you add `@nuxtjs/i18n` to `modules` and configure `i18n.locales` in `nuxt.config.ts`, localized routing, per-locale content collections, the language switcher, and multilingual SEO activate automatically.

Either way, pages access the current locale, the translation function, and localized paths through a single entry point, `useMovkI18n()`, with consistent behavior.

## Single-language UI

When `@nuxtjs/i18n` is not enabled, set the UI language via `app.config.ts`. It decides which language the built-in UI strings (TOC title, edit link, AI assistant, etc.) use.

```ts [app.config.ts]
export default defineAppConfig({
  i18n: {
    locale: 'en' // UI language, defaults to 'zh-CN'
  }
})
```

Built-in language packs currently provide `zh-CN` and `en`. In this mode URLs carry no locale prefix and the content directory stays single-structured.

## Multilingual site

### 1. Install the dependency

Multilingual requires installing `@nuxtjs/i18n` manually (the layer does not pull it in):

```bash [npm]
npm install @nuxtjs/i18n
```

```bash [pnpm]
pnpm add @nuxtjs/i18n
```

```bash [yarn]
yarn add @nuxtjs/i18n
```

```bash [bun]
bun add @nuxtjs/i18n
```

### 2. Configure nuxt.config.ts

Add `@nuxtjs/i18n` to `modules` and declare `defaultLocale` and `locales`:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  extends: ['@movk/nuxt-docs'],

  modules: ['@nuxtjs/i18n'],

  i18n: {
    defaultLocale: 'zh-CN',
    locales: [
      { code: 'zh-CN', name: '简体中文', file: 'zh-CN.json' },
      { code: 'en', name: 'English', file: 'en.json' }
    ]
  }
})
```

> [!NOTE]
> 
> The layer forces the routing strategy to 
> 
> prefix_except_default
> 
> : the 
> 
> default locale has no prefix
> 
>  (
> 
> /docs
> 
> ), while others are prefixed (
> 
> /en/docs
> 
> ). You do not need to set 
> 
> strategy
> 
>  manually.

### 3. Organize content directories

Default-locale content stays in place at the `content/` root; other locales live under `content/{locale}/`:

```bash
content/
├── index.md              # Default locale (zh-CN) home
├── docs/                 # Default locale docs → /docs/*
│   └── 1.getting-started/
│       └── 1.index.md
└── en/                   # English content
    ├── index.md          # English home → /en
    └── docs/             # English docs → /en/docs/*
        └── 1.getting-started/
            └── 1.index.md
```

The layer generates content collections per locale automatically: the default locale uses `docs` / `landing`, while others use `docs_{code}` / `landing_{code}` (with `-` replaced by `_` in `code`, e.g. `docs_zh_CN`).

## Translation files

UI strings (navigation, buttons, AI assistant, etc.) come from translation files. The built-in `zh-CN` and `en` live inside the package at `i18n/locales/zh-CN.json` and `i18n/locales/en.json`.

Adding a new language requires meeting two conditions, otherwise the locale is filtered out at build time with a warning:

1. A matching translation file `{code}.json` exists;
2. A matching content directory `content/{code}/` exists (except the default locale, whose content lives at the `content/` root).

UI string resolution order is **app.config.ts override ?? translation file**. So the string fields in `app.config.ts` default to empty and are provided by the current locale's translation file; to override a single entry, set it explicitly in `app.config.ts`.

## Language switcher

Once multilingual is enabled, the site header shows a language switcher (`LanguageSwitcher`) that renders the current locale as a flag emoji, lists all valid locales, and navigates to the equivalent path in the chosen language.

## Multilingual SEO

When i18n is enabled and multiple valid locales exist, the layer injects:

- `<link rel="alternate" hreflang="…">` for each locale plus an `x-default` fallback;
- `og:locale` for the current locale;
- `<html lang/dir>` driven by `@nuxt/ui/locale`.

Browser-language redirection is controlled by `@nuxtjs/i18n`'s `detectBrowserLanguage`; to pin the home page language, disable it in the `i18n` config.

## Unified entry point

Pages, components, and composables access i18n through `useMovkI18n()`, with consistent behavior whether or not i18n is enabled:

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        isEnabled
      </code>
    </td>
    
    <td>
      Whether <code>
        @nuxtjs/i18n
      </code>
      
       is enabled
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        locale
      </code>
    </td>
    
    <td>
      Current locale code (reactive)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        defaultLocale
      </code>
    </td>
    
    <td>
      Default locale code
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        locales
      </code>
    </td>
    
    <td>
      List of valid locales
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        t(key, params?)
      </code>
    </td>
    
    <td>
      Translation function with named params
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        localePath(path)
      </code>
    </td>
    
    <td>
      Convert to the current locale's localized path
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        switchLocalePath(code)
      </code>
    </td>
    
    <td>
      Get the path to switch to a given locale
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        docsRoot
      </code>
    </td>
    
    <td>
      Docs root path (<code>
        /docs
      </code>
      
       or <code>
        /{locale}/docs
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        docsCollection
      </code>
    </td>
    
    <td>
      Current locale's docs collection name
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        landingCollection
      </code>
    </td>
    
    <td>
      Current locale's landing collection name
    </td>
  </tr>
</tbody>
</table>

> [!NOTE]
> 
> useMovkI18n().t
> 
>  is the mode-agnostic entry that also works when i18n is disabled; its key is a plain string with no type completion. When i18n is enabled, the layer turns on 
> 
> @nuxtjs/i18n
> 
>  typed messages, so consumer code that needs key completion should use the native 
> 
> const { t } = useI18n()
> 
> , which automatically recognizes both the layer's built-in keys and the consumer's custom keys.

## Template

For a ready-to-use multilingual site, use the official i18n template:

```bash
npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/i18n my-docs
```

The template ships with `zh-CN` (default) and `en`, the matching content directories, and a preconfigured `@nuxtjs/i18n` setup.


## Sitemap

See the full [sitemap](https://docs.mhaibaraai.cn/sitemap.md) for all pages.
