The principle of internationalization is that it should be possible to make a
Drupal site in any language (or a multi-lingual site), where only content in
the desired language is displayed for any particular page request. In order
to make this happen, developers of modules, themes, and installation profiles
need to make sure that all of the displayable content and user interface (UI)
text that their project deals with is internationalized properly, so that it
can be translated using the standard Drupal translation mechanisms.

Internationalization

Different types of information in Drupal have
different methods for internationalization, and different portions of the
UI also have different methods for internationalization. Here is a list of
the different mechanisms for internationalization, and some notes:

Dates displayed in the UI should be passed through the 'date' service
class's format() method. Again see the Services topic; the method to
call is \Drupal\Core\Datetime\Date::format().

Some YML files contain UI text that is automatically translatable:

*.routing.yml files: route titles. This also applies to
*.links.task.yml, *.links.action.yml, and *.links.contextual.yml files.

*.info.yml files: module names and descriptions.

For configuration, make sure any configuration that is displayable to
users is marked as translatable in the configuration schema. Configuration
types label, text, and date_format are translatable; string is
non-translatable text. See the Config API topic
for more information.

For annotation, make sure that any text that is displayable in the UI
is wrapped in @Translation(). See the
Plugin translatables topic for more
information.

Content entities are translatable if they have

translatable = TRUE,

in their annotation. The use of entities to store user-editable content to
be displayed in the site is highly recommended over creating your own
method for storing, retrieving, displaying, and internationalizing content.

The Interface Translation module deserves special mention, because besides
providing a UI for translating UI text, it also imports community
translations from the
Drupal translation server. If
UI text and provided configuration in Drupal Core and contributed modules,
themes, and installation profiles is properly internationalized (as described
above), the text is automatically added to the translation server for
community members to translate, via *.po files that are generated by
scanning the project files.

Translation string sharing and context

By default, translated strings are only translated once, no matter where
they are being used. For instance, there are many forms with Save
buttons on them, and they all would have t('Save') in their code. The
translation system will only store this string once in the translation
database, so that if the translation is updated, all forms using that text
will get the updated translation.

Because the source of translation strings is English, and some words in
English have multiple meanings or uses, this centralized, shared translation
string storage can sometimes lead to ambiguous translations that are not
correct for every place the string is used. As an example, the English word
"May", in a string by itself, could be part of a list of full month names or
part of a list of 3-letter abbreviated month names. So, in languages where
the month name for May is longer than 3 letters, you'd need to translate May
differently depending on how it's being used. To address this problem, the
translation system includes the concept of the "context" of a translated
string, which can be used to disambiguate text for translators, and obtain
the correct translation for each usage of the string.

Here are some examples of how to provide translation context with strings, so
that this information can be included in *.po files, displayed on the
localization server for translators, and used to obtain the correct
translation in the user interface: