Translations and languages
For a site to work in several languages, interface texts are not written directly in views but passed through a translation function. It looks the string up in the translation file of the current language. This area is called i18n, short for internationalization.
The application language
Two languages are set in config/web.php:
// config/web.php
$config = [
'sourceLanguage' => 'en-US',
'language' => 'de-DE',
// ...
];sourceLanguage is the language the strings are written in inside the code (English by default), language is the language they must be translated into. Messages of the framework itself, such as form errors and button labels, become German after that.
The translation function
In views text is wrapped in Yii::t():
<?php
// views/post/index.php
?>
<h1><?= Yii::t('app', 'Posts') ?></h1>The first argument is the category, that is the name of the translation file; app is the convention for your own texts. The second is the source string. Until there is a translation, the page keeps showing "Posts".
The translation file
Translations live in the messages folder, in a subfolder with the language code. Create messages/de-DE/app.php by hand:
// messages/de-DE/app.php
return [
'Posts' => 'Artikel',
'Read more' => 'Weiterlesen',
'Hello, {name}!' => 'Hallo, {name}!',
];Refresh the page and the heading becomes "Artikel". The app category and the messages folder work in the standard project without extra configuration.
Inserting values
The changing parts of a string are written in curly braces and passed as the third argument:
echo Yii::t('app', 'Hello, {name}!', ['name' => 'Anna']);The result is "Hallo, Anna!". A translator can move the placeholder as the language requires.
Switching the language
The language can be changed for every request, for example by the visitor's choice stored in the session. The property is set before the page is rendered:
Yii::$app->language = Yii::$app->session->get('language', 'en-US');A convenient place for this line is the beforeAction() method of a common base controller. The choice is saved by a separate action that writes the language code to the session.
Dates and numbers
The formatter component prints dates and numbers by the rules of the current language:
echo Yii::$app->formatter->asDate($post->created_at, 'long'); // 2. März 2026
echo Yii::$app->formatter->asDecimal(1234.5, 2); // 1.234,50
echo Yii::$app->formatter->asCurrency(19.99, 'EUR'); // 19,99 €For English the same calls give "March 2, 2026" and "1,234.50". This formatting requires the intl PHP extension to be enabled.
Your own categories
Other category names are attached in the i18n component:
// config/web.php
'components' => [
'i18n' => [
'translations' => [
'shop*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages',
],
],
],
],The call Yii::t('shop', 'Cart') will look for a translation in the file messages/de-DE/shop.php.
Common mistake
A string must not be assembled from parts: Yii::t('app', 'Hello, ') . $name leaves the translator no way to change the word order, and the key 'Hello, ' with a trailing space is easy to miss in the file. Pass a whole phrase with placeholders in curly braces to Yii::t().