# How to Add a New Language Locale to Folia Using i18next

> Learn how to add a new language locale to Folia using i18next. Follow these steps to create a locale file, register it, and add translations for seamless multilingual support.

- Repository: [冬霧/folia-major](https://github.com/chthollyphile/folia-major)
- Tags: how-to-guide
- Published: 2026-07-06

---

**Adding a new language to Folia requires creating a TypeScript locale file in `src/i18n/locales/`, registering it in the i18n configuration, and adding a translation key for the language name in the settings section of your base locale.**

Folia is an open-source document editing application built with React that uses **i18next** and **react-i18next** for internationalization. If you need to add a new language locale to Folia using i18next, the process involves three core tasks: creating a translation file that matches the existing schema, registering it in the i18next configuration, and exposing it in the settings UI so users can select it from the command palette.

## Step 1: Create the Locale Translation File

Create a new TypeScript file at `src/i18n/locales/<lang>.ts` (e.g., [`fr.ts`](https://github.com/chthollyphile/folia-major/blob/main/fr.ts) for French) that exports a default object containing all translation keys. According to the Folia source code, this file must mirror the structure of the reference English locale in [`src/i18n/locales/en.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/locales/en.ts) to ensure all UI strings are covered.

The file should export a flat object with nested keys for different sections like `status`, `commandPalette`, `ui`, and `settings`. Here is a partial example for French:

```typescript
export default {
  "status": {
    "sessionRestored": "Session restaurée",
    "loadedDefaultDemo": "Démo par défaut chargée"
  },
  "commandPalette": {
    "placeholder": "Tapez une commande ou recherchez…"
  },
  "settings": {
    "languageSettings": "Langue",
    "appLanguage": "Langue de l’interface",
    "appLanguageDesc": "Définissez manuellement la langue de Folia ou revenez au suivi du système.",
    "appLanguageSystem": "Suivre le système",
    "appLanguageFrFR": "Français"
  }
} as const;

```

Copy the complete structure from [`src/i18n/locales/en.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/locales/en.ts) and translate only the string values, keeping the key names identical.

## Step 2: Register the Locale in i18next Configuration

Open [`src/i18n/config.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/config.ts) and import your new locale module. Add it to the `resources` object that i18next consumes during initialization. The configuration also defines the **fallback language** (`fallbackLng`) and detection order, which automatically handles browser language detection.

```typescript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import en from './locales/en';
import zhCN from './locales/zh-CN';
import fr from './locales/fr';          // <─ NEW IMPORT

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources: {
      en,
      zh: zhCN,
      fr,                               // <─ NEW RESOURCE
    },
    fallbackLng: 'en',
    detection: {
      order: ['localStorage', 'navigator'],
      lookupLocalStorage: 'i18nextLng',
    },
    interpolation: { escapeValue: false },
  });

export default i18n;

```

The `resources` map keys (e.g., `fr`, `zh`) become the language codes available to the application.

## Step 3: Expose the Language in the Settings UI

To make the language selectable in Folia's **command palette** and settings panel, add a translation entry in the `settings` section of your base locale file (typically [`src/i18n/locales/en.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/locales/en.ts)). The settings store at [`src/stores/useSettingsUiStore.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/stores/useSettingsUiStore.ts) automatically reads these keys to populate the language picker without requiring additional code changes.

Add a new key following the pattern `appLanguage<LangCode>` (e.g., `appLanguageFrFR`) to the settings object:

```typescript
"settings": {
  "appLanguageSystem": "System",
  "appLanguageEnUS": "English",
  "appLanguageZhCN": "Chinese (Simplified)",
  "appLanguageFrFR": "French"          // <─ NEW ENTRY
}

```

Once added, the language switcher in [`src/components/command-palette/CommandPalette.tsx`](https://github.com/chthollyphile/folia-major/blob/main/src/components/command-palette/CommandPalette.tsx) will automatically display the new option using the `useTranslation` hook.

## Key Implementation Details

- **File Structure**: All locale files reside in `src/i18n/locales/` and use TypeScript const assertions for type safety.
- **Automatic Detection**: The `LanguageDetector` plugin checks `localStorage` first, then the browser's navigator settings, so returning users will see their previously selected language.
- **No Component Changes**: Because Folia's UI components consume translations dynamically via `useTranslation`, you do not need to modify React components to support the new language.

## Summary

- **Create** a new locale file at `src/i18n/locales/<lang>.ts` by copying and translating [`src/i18n/locales/en.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/locales/en.ts).
- **Register** the locale in [`src/i18n/config.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/config.ts) by importing it and adding it to the `resources` object.
- **Expose** the language name in the settings section of your base locale using the `appLanguage<LangCode>` key pattern.
- **Test** by running the application—the new language appears instantly in Settings → Language without rebuilding the UI components.

## Frequently Asked Questions

### Where are translation files stored in Folia?

Translation files are stored in the `src/i18n/locales/` directory. Each file is a TypeScript module that exports a default object containing nested translation keys, such as [`en.ts`](https://github.com/chthollyphile/folia-major/blob/main/en.ts) for English and [`zh-CN.ts`](https://github.com/chthollyphile/folia-major/blob/main/zh-CN.ts) for Chinese (Simplified).

### Do I need to modify the language switcher component?

No. The language switcher in [`src/components/command-palette/CommandPalette.tsx`](https://github.com/chthollyphile/folia-major/blob/main/src/components/command-palette/CommandPalette.tsx) uses the `useTranslation` hook from react-i18next to dynamically render available languages. As long as you add the language name key to the settings section of your translation file, the store at [`src/stores/useSettingsUiStore.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/stores/useSettingsUiStore.ts) automatically includes it in the UI.

### What happens if a translation key is missing in the new locale?

i18next falls back to the `fallbackLng` specified in [`src/i18n/config.ts`](https://github.com/chthollyphile/folia-major/blob/main/src/i18n/config.ts) (defaults to English). If a specific key is missing in the new locale, the user will see the English translation instead of a blank string or error.

### How do I test the new locale without changing browser settings?

You can manually set the language by calling `i18n.changeLanguage('fr')` (replacing `'fr'` with your locale code) in the browser console, or by modifying the `i18nextLng` value in localStorage and refreshing the page.