Lets dive deeper into how Magento 2 generates the translations. Lets start at the very surface - the one thing we can see from the browser.
We know that in localstorage the translations are stored with key mage-translation-storage. So lets search for this key in the core code.
First the code checks if the object already exists and if the version is newer than what we currently have. If we have a newer version we load the dictionary file which is later passed to translations components which translate the strings in javascript. Some more details on this can be found in this post.
The js-translation.json is located at the theme root for example pub/static/frontend/Vendor/theme/en_US/js-translation.json
The file is automatically generated during static content deploy. Lets keep going backwards to see the flow.
php bin/magento setup:static-content:deploy
The file is deployed in module-deploy/Service/DeployTranslationsDictionary.php which is called in deploy during static content deploy.
The file itself however is generated in Preprocessor class which is responsible for providing javascript translation dictionary.
As we can see in the function the actual data however is gathered in the \Magento\Translation\Model\Js\DataProvider
A couple things happening here:
First we are getting all the js files using \Magento\Translation\Model\Js\DataProvider::$filesUtility.
Then we are going through each file path, reading the file content and parsing translation phrases using \Magento\Translation\Model\Js\DataProvider::getPhrases.
Once we have found a phrase we are attempting to render it using \Magento\Framework\Phrase\Renderer\Composite::render
The composite renderer is defined in translation modules di.xml:
Once we have rendered the translation we compare it with the original phrase. If the translation differs then we add it to the dictionary.
Ok, now we know how the file content is generated. Last step is to understand how the file genration is triggered. If we take a look at the usages of the class we can see that the processor is defined here:
The JS\PreProcessor is responsible for replacing translation calls in js files to translated strings. The PreProcessor pool is implemented in framework \Magento\Framework\View\Asset\PreProcessor\Pool.
The pool process is calling getPreProcessors which picks up our class:
The Pool itself is trigger by a call in \Magento\Framework\App\View\Asset\Publisher::publishAsset which occurs during \Magento\Deploy\Service\DeployStaticFile::deployFile.
Since we have come back to the static content generation we have travelled through the lifecycle of the javascript translations generation. That is as far as we go.
Normally you will never have to go as deep in core code but it is quite interesting to browse through and can be useful in case any bugs appear.
The functionality itself can be simplified to the following: during static content generation we are gathering all javascript files and parsing them for any translatable strings using regex. All of the translatable strings are attempted to be translated using the available renderer. If the translation differs from the original string the value the key -> value pair is added to the dictionary. The dictionary is saved in a file. Later when user visits the page the file is used by translations initialization and it updates the localstorage dictionary with the newest version of the strings. Finally the translations component is looking for strings in the dictionary and if it can find a match will translate.
This is fairly optimal since we can process everything during static content deployment, then load the translations once and use browser storage to work with javascript components.
Hopefully this does give you a bit of insight on how the process works. It is certainly fun to go through and see various methods and strategies used in Magento 2 core.