Add Bulgarian language support (#13147)

### What problem does this PR solve?

RAGFlow supports 12 UI languages but does not include Bulgarian. This PR
adds Bulgarian (`bg` / `Български`) as the 13th supported language,
covering the full UI translation (2001 keys across all 26 sections) and
OCR/PDF parser language mapping.

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

### Changes

- **`web/src/constants/common.ts`** — Registered Bulgarian in all 5
language data structures (`LanguageList`, `LanguageMap`,
`LanguageAbbreviation` enum, `LanguageAbbreviationMap`,
`LanguageTranslationMap`)
- **`web/src/locales/config.ts`** — Added lazy-loading dynamic import
for the `bg` locale
- **`web/src/locales/bg.ts`** *(new)* — Full Bulgarian translation file
with all 26 sections, matching the English source (`en.ts`). All
interpolation placeholders, HTML tags, and technical terms are preserved
as-is
- **`deepdoc/parser/mineru_parser.py`** — Mapped `'Bulgarian'` to
`'cyrillic'` in `LANGUAGE_TO_MINERU_MAP` for OCR/PDF parser support

### How it works

The language selector automatically picks up the new entry. When a user
selects "Български", the translation bundle is lazy-loaded on demand.
The preference is persisted to the database and localStorage across
sessions.
This commit is contained in:
Trifon
2026-02-14 10:51:29 +02:00
committed by GitHub
parent f612d2254d
commit ce71d87867
17 changed files with 2674 additions and 0 deletions

View File

@@ -73,6 +73,7 @@ LANGUAGE_TO_MINERU_MAP = {
'Thai': 'th',
'Greek': 'el',
'Hindi': 'devanagari',
'Bulgarian': 'cyrillic',
}

View File

@@ -54,6 +54,7 @@ export const LanguageList = [
'German',
'French',
'Italian',
'Bulgarian',
];
export const LanguageMap = {
English: 'English',
@@ -68,6 +69,7 @@ export const LanguageMap = {
German: 'German',
French: 'Français',
Italian: 'Italiano',
Bulgarian: 'Български',
};
export enum LanguageAbbreviation {
@@ -83,6 +85,7 @@ export enum LanguageAbbreviation {
De = 'de',
Fr = 'fr',
It = 'it',
Bg = 'bg',
}
export const LanguageAbbreviationMap = {
@@ -98,6 +101,7 @@ export const LanguageAbbreviationMap = {
[LanguageAbbreviation.De]: 'Deutsch',
[LanguageAbbreviation.Fr]: 'Français',
[LanguageAbbreviation.It]: 'Italiano',
[LanguageAbbreviation.Bg]: 'Български',
};
export const LanguageTranslationMap = {
@@ -121,6 +125,7 @@ export const LanguageTranslationMap = {
Greek: 'el',
Hindi: 'hi',
Ukrainian: 'uk',
Bulgarian: 'bg',
};
export enum FileMimeType {

View File

@@ -0,0 +1,54 @@
# Add Bulgarian Language Support
**Repository:** https://github.com/trifonnt/ragflow
## Overview
Added Bulgarian (`bg` / `Български`) as the 13th supported UI language in RAGFlow.
## Changed Files
### `web/src/constants/common.ts`
Registered Bulgarian in all 5 language data structures:
- **`LanguageList`** — Added `'Bulgarian'` to the array of available languages
- **`LanguageMap`** — Added `Bulgarian: 'Български'` mapping English name to native name
- **`LanguageAbbreviation`** enum — Added `Bg = 'bg'` using ISO 639-1 code
- **`LanguageAbbreviationMap`** — Added `[LanguageAbbreviation.Bg]: 'Български'` for the language selector display
- **`LanguageTranslationMap`** — Added `Bulgarian: 'bg'` for language code resolution
### `web/src/locales/config.ts`
Added a lazy-loading dynamic import entry for the Bulgarian locale file:
```typescript
[LanguageAbbreviation.Bg]: () => import('./bg'),
```
This ensures the Bulgarian translation bundle is only loaded on demand when a user selects it.
### `web/src/locales/bg.ts` (new file)
Created the full Bulgarian translation file containing all 26 sections and 2001 translation keys, matching the English source (`en.ts`) exactly:
`common`, `login`, `header`, `memories`, `memory`, `knowledgeList`, `knowledgeDetails`, `knowledgeConfiguration`, `chunk`, `chat`, `setting`, `message`, `fileManager`, `flow`, `llmTools`, `modal`, `mcp`, `search`, `language`, `pagination`, `dataflowParser`, `datasetOverview`, `deleteModal`, `empty`, `admin`, `explore`
All interpolation placeholders (`{{variable}}`), HTML tags, and technical terms (model names, URLs, API references) are preserved as-is.
### `deepdoc/parser/mineru_parser.py`
Added Bulgarian to the `LANGUAGE_TO_MINERU_MAP` dictionary for OCR/PDF parser language support:
```python
'Bulgarian': 'cyrillic',
```
Bulgarian uses the Cyrillic script, so the `'cyrillic'` MinerU language code is used.
## How It Works
- The language selector in the header automatically picks up the new entry from `LanguageList` and `LanguageMap`
- When a user selects "Български", `changeLanguageAsync('bg')` lazy-loads `bg.ts` and switches the UI
- The user's preference is saved to the database and localStorage for persistence across sessions
- `supportedLngs` in i18next is derived from `Object.values(LanguageAbbreviation)`, so adding `Bg` to the enum automatically registers it

2596
web/src/locales/bg.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@ const languageImports: Record<string, () => Promise<{ default: any }>> = {
[LanguageAbbreviation.De]: () => import('./de'),
[LanguageAbbreviation.Fr]: () => import('./fr'),
[LanguageAbbreviation.It]: () => import('./it'),
[LanguageAbbreviation.Bg]: () => import('./bg'),
};
const enFlattened = flattenObject(translation_en);

View File

@@ -28,6 +28,7 @@ export default {
chinese: 'Vereinfachtes Chinesisch',
traditionalChinese: 'Traditionelles Chinesisch',
russian: 'Russisch',
bulgarian: 'Bulgarisch',
german: 'Deutsch',
language: 'Sprache',
languageMessage: 'Bitte geben Sie Ihre Sprache ein!',
@@ -2388,6 +2389,7 @@ Wichtige strukturierte Informationen können sein: Namen, Daten, Orte, Ereigniss
korean: 'Koreanisch',
vietnamese: 'Vietnamesisch',
russian: 'Russisch',
bulgarian: 'Bulgarisch',
},
pagination: {
total: 'Gesamt {{total}}',

View File

@@ -27,6 +27,7 @@ export default {
chinese: 'Simplified Chinese',
traditionalChinese: 'Traditional Chinese',
russian: 'Russian',
bulgarian: 'Bulgarian',
language: 'Language',
languageMessage: 'Please input your language!',
languagePlaceholder: 'select your language',
@@ -2363,6 +2364,7 @@ Important structured information may include: names, dates, locations, events, k
korean: 'Korean',
vietnamese: 'Vietnamese',
russian: 'Russian',
bulgarian: 'Bulgarian',
},
pagination: {
total: 'Total {{total}}',

View File

@@ -19,6 +19,7 @@ export default {
portugueseBr: 'Portugués (Brasil)',
chinese: 'Chino simplificado',
traditionalChinese: 'Chino tradicional',
bulgarian: 'Búlgaro',
language: 'Idioma',
languageMessage: '¡Por favor ingresa tu idioma!',
languagePlaceholder: 'Selecciona tu idioma',

View File

@@ -19,6 +19,7 @@ export default {
portugueseBr: 'Portugais (Brésil)',
chinese: 'Chinois simplifié',
traditionalChinese: 'Chinois traditionnel',
bulgarian: 'Bulgare',
language: 'Langue',
languageMessage: 'Veuillez saisir votre langue !',
languagePlaceholder: 'Sélectionnez votre langue',

View File

@@ -19,6 +19,7 @@ export default {
portugueseBr: 'Portugis (Brasil)',
chinese: 'Cina',
traditionalChinese: 'Cina Tradisional',
bulgarian: 'Bulgaria',
language: 'Bahasa',
languageMessage: 'Silakan masukkan bahasa Anda!',
languagePlaceholder: 'Pilih bahasa Anda',

View File

@@ -27,6 +27,7 @@ export default {
chinese: 'Cinese semplificato',
traditionalChinese: 'Cinese tradizionale',
russian: 'Russo',
bulgarian: 'Bulgaro',
italian: 'Italiano',
german: 'Tedesco',
french: 'Francese',
@@ -1190,6 +1191,7 @@ Quanto sopra è il contenuto che devi riassumere.`,
korean: 'Coreano',
vietnamese: 'Vietnamita',
russian: 'Russo',
bulgarian: 'Bulgaro',
},
pagination: {
total: 'Totale {{total}}',

View File

@@ -19,6 +19,7 @@ export default {
portugueseBr: 'ポルトガル語 (ブラジル)',
chinese: '中国語(簡体字)',
traditionalChinese: '中国語(繁体字)',
bulgarian: 'ブルガリア語',
language: '言語',
languageMessage: 'あなたの言語を入力してください!',
languagePlaceholder: 'あなたの言語を選択してください',

View File

@@ -18,6 +18,7 @@ export default {
portugueseBr: 'Português (Brasil)',
chinese: 'Chinês Simplificado',
traditionalChinese: 'Chinês Tradicional',
bulgarian: 'Búlgaro',
language: 'Idioma',
languageMessage: 'Por favor, insira seu idioma!',
languagePlaceholder: 'selecione seu idioma',

View File

@@ -26,6 +26,7 @@ export default {
chinese: 'Китайский упрощенный',
traditionalChinese: 'Китайский традиционный',
russian: 'Русский',
bulgarian: 'Болгарский',
language: 'Язык',
languageMessage: 'Пожалуйста, укажите ваш язык!',
languagePlaceholder: 'выберите ваш язык',
@@ -2036,6 +2037,7 @@ export default {
korean: 'Корейский',
vietnamese: 'Вьетнамский',
russian: 'Русский',
bulgarian: 'Болгарский',
},
pagination: {
total: 'Всего {{total}}',

View File

@@ -18,6 +18,7 @@ export default {
portugueseBr: 'Tiếng Bồ Đào Nha (Brazil)',
chinese: 'Tiếng Trung giản thể',
traditionalChinese: 'Tiếng Trung phồn thể',
bulgarian: 'Tiếng Bulgaria',
language: 'Ngôn ngữ',
languageMessage: 'Vui lòng chọn ngôn ngữ của bạn!',
languagePlaceholder: 'chọn ngôn ngữ của bạn',

View File

@@ -18,6 +18,7 @@ export default {
portugueseBr: '葡萄牙語 (巴西)',
chinese: '簡體中文',
traditionalChinese: '繁體中文',
bulgarian: '保加利亞語',
language: '語言',
languageMessage: '請輸入語言',
languagePlaceholder: '請選擇語言',

View File

@@ -26,6 +26,7 @@ export default {
portugueseBr: '葡萄牙语 (巴西)',
chinese: '简体中文',
traditionalChinese: '繁体中文',
bulgarian: '保加利亚语',
language: '语言',
languageMessage: '请输入语言',
languagePlaceholder: '请选择语言',
@@ -2107,6 +2108,7 @@ Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
japanese: '日语',
korean: '韩语',
vietnamese: '越南语',
bulgarian: '保加利亚语',
},
pagination: {
total: '总共 {{total}} 条',