The frontend uses Nuxt’s i18n module to support internationalization, enabling localization of the user interface.

WordPress uses GlotPress for managing translations, which is built on top of the gettext standard. On the other hand, Nuxt (and most JS-based i18n libraries) use JSON for managing translations. This disconnect means that Openverse translations must convert from JSON to POT and back again. Hence there is quite a bit of scaffolding involved.

Upload pipeline#

This pipeline deals with how translations strings are extracted from the frontend application and provided to GlotPress for translation.


  • Create a POT file from the en.json5 file.

    Script: i18n:generate-pot

  • Upload this POT file to a fixed URL. Currently the file is hosted in the translations branch of the WordPress/openverse repo.

  • GlotPress presents the strings, fuzzy translations and other helpful context to translators in a web UI to help them provide a translation.

Download pipeline#

This pipeline deals with how translations are retrieved from GlotPress, processed and loaded into Nuxt via the Nuxt i18n module.


  • Parse and extract the list of all locales from GlotPress’s PHP source code. Then narrow down the list to locales available in the WP GlotPress instance and populate their coverage percentage from the GlotPress stats.

    The output is written to wp-locales.json.

    Script: i18n:create-locales-list

  • Download all translations from GlotPress as JED 1.x JSON files. The flattened JED 1.x (derived from the flattened POT files) files are converted back into the nested JSON as expected by Nuxt i18n.

    This script downloads all available translations in bulk as a ZIP file and then extracts JSON files from the ZIP file. This prevents excessive calls to GlotPress, which can be throttled and cause some locales to be missed.

    Script: i18n:get-translations

  • Separate the locales into three groups based on the JSON files emitted by i18n:get-translations.

    • translated: JSON file is present with mappings, written to valid-locales.json.

    • untranslated: JSON file is present but empty, written to both valid-locales.json and untranslated-locales.json.

    • invalid: JSON file is not present, written to invalid-locales.json.

    Script: i18n:update-locales

  • Pass the list of valid locales (along with extra fields) into the Nuxt i18n module. This is configured in the Nuxt configuration file, nuxt.config.ts.

  • Pass the fallback locale mappings to the underlying Vue i18n plugin. This is configured in the plugin configuration file, frontend/src/plugins/vue-i18n.ts.