We use Transifex to translate Sentry.

Other things that mean translating: localization, internationalization, i18n, l10n

If you need access to manage translations, translators, languages, or anything else, please talk to one of the following people:

  • Ben Vinegar
  • Vlad Cretu

Approving Translators and Languages

General rules to follow when doing approvals.

  1. Don't approve new languages generally.
  2. Don't approve new languages that are duplicates of existing languages.
  3. Don't approve new team members unless they seem reliable (see security note below).

Backfilling a Language

We have the ability to pay translators to come in and backfill a language. This has been done a number of times over the years, and is a good way to get an acceptable amount of coverage. There are caveats however:

  • They often need "context" for a string, which we're usually missing in our code (or in the database). This means someone has to respond to their requests.
  • The quality will be average - you given them a style to aim for, and they often do an ok-enough job.
  • It's not free, though its cheap so it's not a big deal.

Translation Security

It's possible for translators to inject advertisements (links) or other bad content into translations. For this reason we don't accept translations implicitly - you get approved first - but it means we also need to do at least a minor bit of research on the translator themselves. Generally this is left to your own judgement, but take a look at their profile and ask yourself if they seem like a real human, or if this is a one-off account intended to use for abuse.

Updating Translations (source code)

Translations have to be updated manually in Sentry.

To update untranslated strings in Transifex, open a terminal within the Sentry repo and run the following:

make update-transifex

This will extract strings from the frontend using a webpack loader, as well as from the backend using django makemessages -- which then gets merged together to create a django.po file for the default (English) locale. This then gets propagated to our other supported locales.

It then uploads these PO files to Transifex to be translated. Ideally, this process is automated so that it is run on a schedule to ensure that new strings are synced with Transifex.

Note: You may need to go to Transifex and approve some previously reviewed translations. You can select a language and query for reviewed:no origin:TM to find strings that have shifted around in the source code but have been previously translated. The TM stands for Translation Memory.

Updating Sentry with New Translations

The process of updating Sentry should be separate from updating Transifex as there needs to be time for translations and reviews to occur. In order to update Sentry run the following command in the Sentry repo:

make update-local-locales

This will pull translations from Transifex and use django compilemessages to update the local translations. You should then commit the changes and submit a new Pull Request.


You may encounter some errors when running make update-local-locales.

LC_MESSAGES/django.po:4790: number of format specifications in 'msgid_plural' and 'msgstr[0]' does not match

This means that we are using tn() with an unbalanced set of string placeholders. For example,

tn('one user', '%s users', userCount); // This is bad because the first argument needs to also have %s

// Instead do something like this
userCount === 1 ? t('one user') : tn('%s users', '%s users', userCount); // Not great as the first arg to `tn()` is always ignored, but at least it will compile

Another common error you may see is

LC_MESSAGES/django.po:10824: 'msgstr' is not a valid Python format string, unlike 'msgid'. Reason: The character that terminates the directive number 1 is not a valid conversion specifier.

This generally means there is a literal % that the parser is confusing for a string placeholder. For example,

#: static/app/views/dashboardsV2/manage/dashboardList.tsx:120
#, python-format
msgid "100% of releases"

This can be resolved by removing #, python-format (assuming you don't have any string formatting)

You can edit this page on GitHub.