Multi-Language Support: Maintaining Your Own i18n CSV Files Correctly
Multi-Language Support: Maintaining Your Own i18n CSV Files Correctly
~5 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026
Every visible string in this module - the account menu item from chapter 52, the redeem controller's error message from chapter 50, a System/Config field label from chapter 7 - flows through Magento's own translation system as soon as it's wrapped in __(). The translation itself doesn't live in code, it lives in plain CSV files inside the module: i18n/de_DE.csv and i18n/en_US.csv.
Every translated string, always with __()
The source text of a phrase call stays English by convention - exactly as Magento core does it, and fitting this project, where code comments are always in English (see CLAUDE.md). The German version is produced exclusively through the CSV file, never through a second __() line in the code.
// Placeholder instead of string concatenation - otherwise the CSV key never matches exactly:
throw new LocalizedException(
__('You need %1 more points to redeem this reward.', $missingPoints)
);
// Wrong - the source string changes with every $missingPoints value,
// a CSV translation can never match it:
throw new LocalizedException(
__('You need ' . $missingPoints . ' more points to redeem this reward.')
);The CSV format
Two columns, no header row: source string, translation. UTF-8 without a byte order mark, commas and quotes inside a value escaped with double quotes, exactly like standard CSV.
"My Points","Meine Punkte"
"Redeem Reward","Prämie einlösen"
"You need %1 more points to redeem this reward.","Du brauchst noch %1 Punkte, um diese Prämie einzulösen."
"Reward redemption is temporarily disabled.","Die Einlösung von Prämien ist vorübergehend deaktiviert."Achtung: The source string in the CSV file must match the first argument of the __() call character for character - capitalization, punctuation, even a trailing period all count. If even a single character differs, the translation doesn't apply, and Magento silently falls back to the English source string - no error, no log entry.
Collecting phrases automatically
bin/magento i18n:collect-phrases scans the source code for __() calls and writes newly found phrases into the target CSV, source and translation identical at first - already-present, already-translated lines are left untouched as long as the source string hasn't changed.
bin/magento i18n:collect-phrases app/code/Mironsoft/Loyalty \
-o app/code/Mironsoft/Loyalty/i18n/de_DE.csvTipp: After every run of i18n:collect-phrases, freshly found lines carry an identical source and "translation" in the CSV - a quick diff review before committing reliably shows which lines still need a real German translation.
Clear the cache after every change
Translations run through the translate cache type. A changed CSV line only takes effect outside developer mode after bin/cache-clean translate.
Chapter 90 digs into how this one CSV file per locale spreads across two very different areas: the storefront and the admin interface.