Static Message Translations

Most websites and apps will have some UI messages that are hard-coded into the templates or PHP files. These are called “static messages”, because they aren’t being dynamically defined by content in the CMS.

If you’re building a multilingual site or app, then these messages will need to be translatable just like your CMS-driven content.

To do that, Craft employs Yii’s Message Translations feature, and pre-defines special translation categories:

  • site is used for messages that belong to the project.
  • app is used for Craft Control Panel messages.
  • Each plugin gets its own category as well, based on the plugin’s handle.

Prep Your Messages

The first step is to run all of your static messages through the translator. If you’re working on a template, use the translate filter (|t). If you’re working in PHP code, use Craft::t().

{# old #}
<a href="/contact">Contact us</a>

{# new #}
<a href="/contact">{{ 'Contact us'|t }}</a>

Provide the Translations

Once you’ve prepped a message for translations, you need to supply the actual translation.

To do that, create a new folder in your project’s base directory called translations/, and within that, create a new folder named after the target language’s ID. Within that, create a file named after the translation category you want to create massages for (site.php for project messages, app.php to overwrite Craft's Control Panel messages, or <plugin-handle>.php to overwrite a plugin’s messages).

For example, if you want to translate your project’s messages into German, this is what your project’s directory structure should look like:

├── config/
├── ...
└── translations/
    └── de/
        └── site.php

Now open site.php in a text editor, and have it return an array that maps the source messages to their translated messages.


return [
    'Contact us' => 'Kontaktiere uns',

Now, when Craft is processing the message translation for a German site, “Contact us” will be replaced with “Kontaktiere uns”.

Message Parameters

Static messages can have placeholder values. For example:


return [
    'Welcome back, {name}' => 'Willkommen zurück {name}',

To replace the placeholder values with dynamic values when translating the message, pass the params argument when using the translate filter or calling Craft::t():

<a href="/contact">{{ 'Welcome back, {name}'|t(params = {
    name: currentUser.friendlyName,
}) }}</a>