# Internationalization (i18n) ## Introduction This directory contains i18n tooling and configuration. Translation files live under `web/i18n`. ## File Structure ``` web/i18n ├── en-US │ ├── app.json │ ├── app-debug.json │ ├── common.json │ └── ... └── zh-Hans └── ... web/i18n-config ├── language.ts ├── i18next-config.ts └── ... ``` We use English as the default language. Translation files are organized by language and then by module. For example, the English translation for the `app` module is in `web/i18n/en-US/app.json`. Translation files are JSON with flat keys (dot notation). i18next is configured with `keySeparator: false`, so dots are part of the key. The namespace is the camelCase file name (for example, `app-debug.json` -> `appDebug`), so use `useTranslation('appDebug')` or `t('key', { ns: 'appDebug' })`. If you want to add a new language or modify an existing translation, create or update the `.json` files in the language folder. For example, if you want to add French translation, you can create a new folder `fr-FR` and add the translation files in it. By default we will use `LanguagesSupported` to determine which languages are supported. For example, in login page and settings page, we will use `LanguagesSupported` to determine which languages are supported and display them in the language selection dropdown. ## Example 1. Create a new folder for the new language. ``` cd web/i18n cp -r en-US id-ID ``` 2. Modify the translation `.json` files in the new folder. Keep keys flat (for example, `dialog.title`). 1. Add the new language to the `languages.ts` file. ```typescript export const languages = [ { value: 'en-US', name: 'English(United States)', example: 'Hello, Dify!', supported: true, }, { value: 'zh-Hans', name: '简体中文', example: '你好,Dify!', supported: true, }, { value: 'pt-BR', name: 'Português(Brasil)', example: 'Olá, Dify!', supported: true, }, { value: 'es-ES', name: 'Español(España)', example: 'Saluton, Dify!', supported: false, }, { value: 'fr-FR', name: 'Français(France)', example: 'Bonjour, Dify!', supported: false, }, { value: 'de-DE', name: 'Deutsch(Deutschland)', example: 'Hallo, Dify!', supported: false, }, { value: 'ja-JP', name: '日本語 (日本)', example: 'こんにちは、Dify!', supported: false, }, { value: 'ko-KR', name: '한국어 (대한민국)', example: '안녕, Dify!', supported: true, }, { value: 'ru-RU', name: 'Русский(Россия)', example: ' Привет, Dify!', supported: false, }, { value: 'it-IT', name: 'Italiano(Italia)', example: 'Ciao, Dify!', supported: false, }, { value: 'th-TH', name: 'ไทย(ประเทศไทย)', example: 'สวัสดี Dify!', supported: false, }, { value: 'id-ID', name: 'Bahasa Indonesia', example: 'Halo, Dify!', supported: true, }, { value: 'uk-UA', name: 'Українська(Україна)', example: 'Привет, Dify!', supported: true, }, { value: 'fa-IR', name: 'Farsi (Iran)', example: 'سلام, دیفای!', supported: true, }, { value: 'ar-TN', name: 'العربية (تونس)', example: 'مرحبا، Dify!', supported: true, }, // Add your language here 👇 // ... // Add your language here 👆 ] ``` 4. Don't forget to mark the supported field as `true` if the language is supported. 1. Sometimes you might need to do some changes in the server side. Please change this file as well. 👇 https://github.com/langgenius/dify/blob/61e4bbabaf2758354db4073cbea09fdd21a5bec1/api/constants/languages.py#L5 > Note: `I18nText` type is automatically derived from `LanguagesSupported`, so you don't need to manually add types. ## Clean Up That's it! You have successfully added a new language to the project. If you want to remove a language, you can simply delete the folder and remove the language from the `languages.ts` file. We have a list of languages that we support in the `languages.ts` file. But some of them are not supported yet. So, they are marked as `false`. If you want to support a language, you can follow the steps above and mark the supported field as `true`. ## Utility scripts - Auto-fill translations: `pnpm run i18n:gen --file app common --lang zh-Hans ja-JP [--dry-run]` - Use space-separated values; repeat `--file` / `--lang` as needed. Defaults to all en-US files and all supported locales except en-US. - Protects placeholders (`{{var}}`, `${var}`, ``) before translation and restores them after. - Check missing/extra keys: `pnpm run i18n:check --file app billing --lang zh-Hans [--auto-remove]` - Use space-separated values; repeat `--file` / `--lang` as needed. Returns non-zero on missing/extra keys; `--auto-remove` deletes extra keys automatically. Workflows: `.github/workflows/translate-i18n-base-on-english.yml` auto-runs the translation generator on `web/i18n/en-US/*.json` changes to main. `i18n:check` is a manual script (not run in CI).