Skip to main content
Lichess is available in over 140 languages thanks to community translators on Crowdin. Your translations help make chess accessible to millions of players worldwide.

Getting Started with Crowdin

1

Create a Crowdin account

Visit Lichess on Crowdin and create a free account.
2

Select your language

Choose the language you want to translate into. If your language isn’t listed, request it in the Crowdin project.
3

Start translating

Browse the translation files and start translating strings. Crowdin provides context and suggestions to help you.

Translate Lichess

Join over 140 languages on Crowdin

Translation Files

Lichess translations are organized in XML files located in /translation/source/:

File Structure

translation/
├── source/          # Source English strings
│   ├── site.xml
│   ├── arena.xml
│   ├── emails.xml
│   └── ...
├── dest/            # Translated strings (auto-generated)
│   ├── site/
│   │   ├── en-US.xml
│   │   ├── es-ES.xml
│   │   └── ...
│   └── ...
└── resources.dtd    # XML validation rules

Source Files

The source/ directory contains the original English strings. These are what you translate on Crowdin.

Destination Files

The dest/ directory contains completed translations. These are automatically generated by Crowdin and should not be edited manually.

Crowdin Configuration

Lichess uses the following Crowdin settings:
crowdin.yml
files:
  - source: /translation/source/*.xml
    translation: /translation/dest/%file_name%/%locale%.%file_extension%
    translate_attributes: 0
    update_option: update_without_changes

What This Means

  • source: English XML files from /translation/source/
  • translation: Output pattern for translated files
  • translate_attributes: XML attributes are not translated (only content)
  • update_option: Translations update even if source hasn’t changed

Translation Workflow

How Translations Get to Production

1

Translate on Crowdin

Contributors translate strings through the Crowdin web interface.
2

Automatic sync

Crowdin automatically syncs approved translations to the Lichess repository.
3

CI validation

GitHub Actions validate the XML files:
  • xmllint checks XML syntax
  • trans-lint checks translation quality
  • i18n-key-check verifies all keys are present
4

Build and deploy

Valid translations are built into the application and deployed to production.

Commit Messages

When translations are synced from Crowdin, commits follow this pattern:
New translations: site.xml (Spanish)

Translation Validation

All translations go through automated validation:

XML Lint

Validates XML structure against the DTD:
xmllint --noout --dtdvalid translation/resources.dtd translation/**/*.xml
This ensures:
  • Proper XML formatting
  • Valid tags and structure
  • No syntax errors

Translation Lint

Custom linting for translation quality:
./bin/trans-lint translation/dest/*/*.xml
This checks:
  • Placeholder consistency (%s, %1$s, etc.)
  • Special character usage
  • HTML tag integrity

i18n Key Check

Verifies that TypeScript i18n files are up-to-date:
pnpm i18n-file-gen
./ui/build --i18n
If you modify translation source files locally, you must run pnpm i18n-file-gen and ./ui/build --i18n to regenerate TypeScript i18n files.

Translation Best Practices

Context Matters

Always consider the context when translating:
<string name="play">Play</string>
<!-- Button to start a game -->
Crowdin provides screenshots and context to help you understand where strings appear.

Preserve Placeholders

Always keep placeholders in translations:
<string name="nbGamesPlayed">%s games played</string>

HTML Tags

Keep HTML tags intact:
<string name="welcome">Welcome to <em>Lichess</em>!</string>

Consistency

Be consistent with terminology:
  • Use the same translation for repeated terms
  • Follow established conventions in your language
  • Check existing translations before adding new ones

Length Considerations

Some UI elements have limited space:
Try to keep translations reasonably close to the original length, especially for buttons and short labels.
If a translation is much longer, it might not fit in the UI.

Contributing Translation Changes Locally

If you need to modify source translation files:

1. Edit Source Files

Modify files in /translation/source/:
vim translation/source/site.xml

2. Regenerate i18n Files

# Generate TypeScript i18n files
pnpm i18n-file-gen

# Build i18n assets
./ui/build --i18n

3. Validate Changes

Run validation locally:
# XML validation
xmllint --noout --dtdvalid translation/resources.dtd translation/**/*.xml

# Translation linting
./bin/trans-lint translation/dest/*/*.xml

# Check i18n files are up to date
git status --porcelain

4. Commit Changes

Only commit source files (translation/source/) and generated i18n TypeScript files. Do not commit destination files (translation/dest/) as these come from Crowdin.
git add translation/source/*.xml
git add ui/@types/lichess/i18n.d.ts
git commit -m "Add new translation keys for feature X"

Translation Coverage

Crowdin Check the Crowdin project page to see translation progress for all languages.

Language Requirements

For a language to be available on Lichess:
  1. Core strings must be fully translated (site.xml, arena.xml, etc.)
  2. Translations must be approved by language moderators
  3. Language must be requested via Crowdin or GitHub issue

Getting Help

Crowdin Support

  • Discussion threads: Use Crowdin’s discussion feature to ask about specific strings
  • Language moderators: Reach out to moderators for your language
  • Crowdin forums: Get help from the Crowdin community

Lichess Community

Recognition

Translators are recognized on:
  • lichess.org/thanks - Thanks page listing all contributors
  • Crowdin project page - Shows top translators
  • About pages - Language-specific acknowledgments

Next Steps

Start Translating

Join Lichess translators on Crowdin

Contributing Overview

Explore other ways to contribute

Build docs developers (and LLMs) love