How to Add New Translations to the Stirling-PDF UI Using Locale Files

Stirling-PDF uses TOML-based locale files rather than JSON to store UI translations. To add a new language, create a directory under frontend/public/locales/, copy the English reference file from en-GB/translation.toml, translate the key-value pairs while preserving placeholders like {n} or {{variable}}, and run the validation scripts in scripts/translations/ before submitting your pull request.

Stirling-PDF implements internationalization using i18next with a custom TomlBackend that loads translation strings from TOML configuration files. While many projects use JSON for localization, the Stirling-Tools/Stirling-PDF repository exclusively uses the TOML format for its standard workflow. If you require JSON for a custom backend integration, the repository provides conversion utilities, but the following guide covers the standard TOML-based approach for adding new UI translations.

Understanding the Translation Architecture

The application stores all UI strings in frontend/public/locales/<language>/translation.toml. The i18next configuration in frontend/src/core/i18n/config.ts initializes the TomlBackend to parse these files at runtime. The LanguageSelector.tsx component automatically detects available languages by reading the subdirectories within frontend/public/locales/, meaning you typically do not need to modify React code to add a new language option.

Step-by-Step Guide to Adding a New Language

1. Create the Language Directory

Use a hyphenated language code following the language-COUNTRY format (e.g., pl-PL, pt-BR, zh-CN). Create the directory structure:

mkdir -p frontend/public/locales/pl-PL

2. Copy the Reference Translation File

Duplicate the English reference file to serve as your translation template. This file contains every translation key used throughout the application:

cp frontend/public/locales/en-GB/translation.toml frontend/public/locales/pl-PL/translation.toml

The en-GB/translation.toml file serves as the master reference maintained by the core team. Always ensure you start with the latest version of this file to avoid missing newly added keys.

3. Translate the TOML Content

Edit the copied file using standard TOML syntax with key = "value" pairs. Preserve all placeholders exactly as they appear in the source text, including {n}, {total}, and {{variable}} formats.


# frontend/public/locales/pl-PL/translation.toml

[convert]
selectSourceFormat = "Wybierz format źródłowego pliku"
selectTargetFormat = "Wybierz format docelowego pliku"

[myFeature]
welcome = "Witamy w mojej funkcji"
description = "Ta funkcja wykonuje X, Y i Z."

4. Register the Language (Automatic Detection)

The frontend/src/core/components/shared/LanguageSelector.tsx component automatically detects new language folders and includes them in the dropdown menu. No code changes are required for basic addition. However, if you want to limit which languages appear in the UI, configure the ui.languages setting in your backend configuration files.

Adding New Translation Keys to Existing Languages

When the UI introduces new features requiring additional text, you must add the keys to the English reference file first:


# frontend/public/locales/en-GB/translation.toml

[newFeature]
welcome = "Welcome to the new feature!"
buttonLabel = "Start Processing"

After updating the English reference, add the corresponding translations to every other language file following the same TOML section structure. Keeping the English file current ensures the validation scripts can detect missing translations in other locales.

Validating Translation Files

Before committing your changes, run the three validation scripts located in scripts/translations/ to ensure TOML syntax integrity, placeholder consistency, and translation completeness:

python3 scripts/translations/validate_json_structure.py --language pl-PL
python3 scripts/translations/validate_placeholders.py --language pl-PL
python3 scripts/translations/translation_analyzer.py --language pl-PL

The validate_placeholders.py script is particularly important—it verifies that variables like {0} or {{username}} remain intact across all language files, preventing runtime errors where the application expects specific interpolation values.

Converting TOML to JSON (Optional)

If you require JSON format for a custom backend implementation, use the conversion utility provided in the repository:

python3 scripts/translations/translation_merger.py

This utility converts the TOML locale files to JSON format. However, for contributing translations back to the main Stirling-Tools/Stirling-PDF repository, you must submit TOML files following the standard workflow described above.

Key Implementation Files

Summary

  • Stirling-PDF uses TOML files stored in frontend/public/locales/<language>/translation.toml, not JSON.
  • Always copy the en-GB/translation.toml reference file when creating a new language translation.
  • Preserve all placeholders like {n} and {{variable}} exactly as they appear in the source text.
  • The LanguageSelector.tsx component automatically detects new language folders without requiring code changes.
  • Run the three validation scripts (validate_json_structure.py, validate_placeholders.py, translation_analyzer.py) to ensure translation quality.
  • Add new keys to the English reference file first, then translate them to other languages.

Frequently Asked Questions

Does Stirling-PDF use JSON files for translations?

No. The UI uses i18next with a custom TomlBackend that expects TOML format files. While the repository includes a translation_merger.py script to convert TOML to JSON for custom backend integrations, the standard workflow and contribution process require TOML files placed in frontend/public/locales/.

How do I add a completely new language that doesn't exist in the repository?

Create a new directory under frontend/public/locales/ using a hyphenated language code (e.g., es-MX for Mexican Spanish), copy the contents of frontend/public/locales/en-GB/translation.toml into it, and translate all values while keeping the keys identical. The language will automatically appear in the UI selector.

Do I need to modify the LanguageSelector component to add my translation?

No. The frontend/src/core/components/shared/LanguageSelector.tsx component dynamically scans the frontend/public/locales/ directory and populates the dropdown based on available folders. You only need to modify the component if you want to implement custom filtering logic beyond the automatic detection.

What happens if I forget to include a placeholder in my translation?

The validate_placeholders.py script will catch missing or modified placeholders during validation. If placeholders like {0}, {n}, or {{variable}} are missing or altered, the application may fail to render dynamic values correctly at runtime, causing broken UI strings or JavaScript errors.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →