How does importing a contrib module's translations work?

cn flag

Drupal version: 9.3.13

Basically, I'm trying to understand how using a contrib module's translation works. I want to be able to download and use the translations from the Drupal infrastructure, and can't seem to get this to work.

I have a site with two languages, English and German (Default). I did run "drush locale-check" and "drush locale-update", and that imported the German core language file (which now is saved at "web/sites/default/files/translations/"). If the current interface language is German, I do see all kinds of core features translated to German.

Active modules:

  • Configuration Translation
  • Interface Translation
  • Language

I then installed a module, first loading it via composer and then installing it via the "admin/modules" page. I made sure that a string of the module was used in a page, that this string is translated on for the current version of the module and that it showed up under "admin/config/regional/translate" as untranslated afterwards. Then I ran both the translation commands again. The output says, that translations for one project were checked and that nothing was changed. No translation showed up for my test string.

I just tested this on a fresh Drupal installation with the "drupal/cookies" module (version 1.0.18, The module's page on shows lots of translated Strings:

What I am aware of:

  • My own custom modules use .po files, and those are loaded just fine.
  • There seems to be a bug that causes new versions of modules not being picked up ( That is also bad, but here no translation for the module is loaded in the first place.

I tried to debug this and got as far as checking "locale.project" and "locale.translation_status" from the "key_value" table. Both only contain Drupal core on my test site. In the production site, all the custom modules are also contained, but none of the contributed modules.

So the question is: What am I missing here? How is this supposed to work?

cn flag
A simple yes or no if loading the translations for contrib modules is supposed to work this way would be helpful. :-)
cn flag

After much debugging I solved this issue by comparing Drupal's behavior with a completely fresh installation. Of course "drush locale-update" is supposed to get translations for contrib modules!

What happened here was this line in the composer.json:

"config": {
     "discard-changes": true,
     "preferred-install": "source",
     "sort-packages": true

The offending line is "preferred-install": "source". This was committed some time ago, nobody knows why and it gets composer to checkout the code from git instead of downloading the zip file from Drupal.

This doesn't make much difference, except that Drupal normally adds information to the info.yml file of the modules:

# Information added by packaging script on 2021-04-02
version: '8.x-1.2'
project: 'foobar'
datestamp: 1617351415

With a git checkout, this is missing! And when Drupal later checks for translations, it goes through all modules and tries to get the project name. Apparently, in Drupal projects are translated, not individual modules. Some modules contain lots of sub-modules, which all share the same project name and therefore the same translation base. Since all my contrib modules came from git rather than from the enhanced zip file, this meant that Drupal skipped them all on "drush locale-update"! No information about this was output, they were simply quietly skipped.

The solution for me was to change the offending line to this:

"preferred-install": {
    "drupal/*": "dist",
    "*": "source"

Also note that you need to delete the modules from web/modules/contrib and reinstall them via composer. Just changing the above and running "composer install" is not enough!


Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.