Add Persian (Farsi) language support (#7876)

## Description

This PR adds Persian (Farsi) language support to ComfyUI. 

## Changes

- Added `fa` to output locales in `.i18nrc.cjs` with Persian-specific
translation guidelines
- Added Persian loaders for all translation files (main, nodeDefs,
commands, settings) in `src/i18n.ts`
- Added Persian (فارسی) option to language settings dropdown in
`src/platform/settings/constants/coreSettings.ts`
- Created empty Persian locale files in `src/locales/fa/` directory
(will be populated by the CI translation system)

## Translation Guidelines

The Persian translation will follow these guidelines:
- Use formal Persian (فارسی رسمی) for professional tone throughout the
UI
- Keep commonly used technical terms in English when they are standard
in Persian software (e.g., node, workflow)
- Use Arabic-Indic numerals (۰-۹) for numbers where appropriate
- Maintain consistency with terminology used in Persian software and
design applications

## Testing

The configuration has been tested to ensure:
- TypeScript compilation succeeds
- All four translation files are properly referenced
- Language option appears correctly in settings

## Notes

Following the contribution guidelines in `src/locales/CONTRIBUTING.md`,
the empty translation files will be automatically populated by the CI
system using OpenAI. Persian-speaking contributors can review and refine
these translations after the automated generation.

---

Special names to keep untranslated: flux, photomaker, clip, vae, cfg,
stable audio, stable cascade, stable zero, controlnet, lora, HiDream,
Civitai, Hugging Face

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7876-Add-Persian-Farsi-language-support-2e16d73d365081f69df0e50048ce87ba)
by [Unito](https://www.unito.io)

Co-authored-by: danialshirali16 <danialshirali16@users.noreply.github.com>
This commit is contained in:
danialshirali16
2026-01-11 09:32:16 +03:30
committed by GitHub
parent e3906a0656
commit 6883241e50
7 changed files with 17 additions and 2 deletions

View File

@@ -10,7 +10,7 @@ module.exports = defineConfig({
entry: 'src/locales/en',
entryLocale: 'en',
output: 'src/locales',
outputLocales: ['zh', 'zh-TW', 'ru', 'ja', 'ko', 'fr', 'es', 'ar', 'tr', 'pt-BR'],
outputLocales: ['zh', 'zh-TW', 'ru', 'ja', 'ko', 'fr', 'es', 'ar', 'tr', 'pt-BR', 'fa'],
reference: `Special names to keep untranslated: flux, photomaker, clip, vae, cfg, stable audio, stable cascade, stable zero, controlnet, lora, HiDream, Civitai, Hugging Face.
'latent' is the short form of 'latent space'.
'mask' is in the context of image processing.
@@ -19,5 +19,11 @@ module.exports = defineConfig({
- For 'zh' locale: Use ONLY Simplified Chinese characters (简体中文). Common examples: 节点 (not 節點), 画布 (not 畫布), 图像 (not 圖像), 选择 (not 選擇), 减小 (not 減小).
- For 'zh-TW' locale: Use ONLY Traditional Chinese characters (繁體中文) with Taiwan-specific terminology.
- NEVER mix Simplified and Traditional Chinese characters within the same locale.
IMPORTANT Persian Translation Guidelines:
- For 'fa' locale: Use formal Persian (فارسی رسمی) for professional tone throughout the UI.
- Keep commonly used technical terms in English when they are standard in Persian software (e.g., node, workflow).
- Use Arabic-Indic numerals (۰-۹) for numbers where appropriate.
- Maintain consistency with terminology used in Persian software and design applications.
`
});

View File

@@ -30,6 +30,7 @@ const localeLoaders: Record<
> = {
ar: () => import('./locales/ar/main.json'),
es: () => import('./locales/es/main.json'),
fa: () => import('./locales/fa/main.json'),
fr: () => import('./locales/fr/main.json'),
ja: () => import('./locales/ja/main.json'),
ko: () => import('./locales/ko/main.json'),
@@ -46,6 +47,7 @@ const nodeDefsLoaders: Record<
> = {
ar: () => import('./locales/ar/nodeDefs.json'),
es: () => import('./locales/es/nodeDefs.json'),
fa: () => import('./locales/fa/nodeDefs.json'),
fr: () => import('./locales/fr/nodeDefs.json'),
ja: () => import('./locales/ja/nodeDefs.json'),
ko: () => import('./locales/ko/nodeDefs.json'),
@@ -62,6 +64,7 @@ const commandsLoaders: Record<
> = {
ar: () => import('./locales/ar/commands.json'),
es: () => import('./locales/es/commands.json'),
fa: () => import('./locales/fa/commands.json'),
fr: () => import('./locales/fr/commands.json'),
ja: () => import('./locales/ja/commands.json'),
ko: () => import('./locales/ko/commands.json'),
@@ -78,6 +81,7 @@ const settingsLoaders: Record<
> = {
ar: () => import('./locales/ar/settings.json'),
es: () => import('./locales/es/settings.json'),
fa: () => import('./locales/fa/settings.json'),
fr: () => import('./locales/fr/settings.json'),
ja: () => import('./locales/ja/settings.json'),
ko: () => import('./locales/ko/settings.json'),

View File

@@ -0,0 +1 @@
{}

1
src/locales/fa/main.json Normal file
View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
{}

View File

@@ -410,7 +410,8 @@ export const CORE_SETTINGS: SettingParams[] = [
{ value: 'es', text: 'Español' },
{ value: 'ar', text: 'عربي' },
{ value: 'tr', text: 'Türkçe' },
{ value: 'pt-BR', text: 'Português (BR)' }
{ value: 'pt-BR', text: 'Português (BR)' },
{ value: 'fa', text: 'فارسی' }
],
defaultValue: () => navigator.language.split('-')[0] || 'en'
},