Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
ICU MessageFormat

Symfony Translation in PHP: A Practical Guide to Internationalization

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Symfony translation becomes straightforward when three pieces line up: a stable message ID, a locale-specific resource, and the user’s selected locale. Install the Translation component, wrap user-facing text in translator calls, add resources for each supported language, and manage the locale on each request. Symfony then chooses the matching catalog, applies fallbacks for missing entries, and returns the original message when no translation exists.

Install and enable Symfony Translation

In a Symfony application, install the component with Composer:

composer require symfony/translation

Symfony’s translation workflow has four parts:

  1. Enable and configure the translation service.
  2. Wrap application messages in translator calls.
  3. Create translation resources for supported locales.
  4. Determine and manage the user’s locale.

Configuration can define a default locale and the directory containing translation resources. A typical application keeps those files in the project’s translations/ directory. The standalone component can also be used directly by creating a translator with a locale, a loader, and a resource; the official component repository documents that minimal setup at github.com/symfony/translation.

Create translation resources

A translation resource maps message IDs to translated text for one locale. Symfony supports YAML, XLIFF/XML, and PHP array resources. The filename identifies both the domain and locale, so follow the naming convention required by the selected format and loader.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

YAML example

# translations/messages.fr.yaml
welcome: 'Bienvenue sur notre site !'
account.logout: 'Se déconnecter'

PHP array example

<?php
// translations/messages.de.php
return [
    'welcome' => 'Willkommen auf unserer Website!',
    'account.logout' => 'Abmelden',
];

Domains keep catalogs organized

The messages portion of a filename is the translation domain. Use additional domains when separating areas such as security, validation, or an administration interface. Pass the domain when calling the translator so Symfony looks in the intended catalog.

Translate messages in PHP and Twig

Inject Symfony’s translator service and translate an ID at the point where text is presented:

use SymfonyContractsTranslationTranslatorInterface;

final class AccountController
{
    public function __construct(
        private TranslatorInterface $translator,
    ) {}

    public function notice(): Response
    {
        $text = $this->translator->trans('account.logout');
        // render or return $text
    }
}

In Twig, use the translation filter or tag:

{{ 'account.logout'|trans }}

Every translatable message needs a stable ID, a resource containing that ID for the target locale, and a locale selected for the current request.

Choose message IDs that survive change

Symfony permits either the original human-readable sentence or a semantic key:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Strategy Example Strength Trade-off
Real message ID Symfony is great Readable and convenient, especially in shared bundles Changing source wording changes the ID throughout every catalog
Semantic key symfony.great Stable when the source-language wording changes; useful for multilingual applications Requires a separate mapping from key to readable text

The official guide leaves this choice to the developer. Prefer semantic keys when long-term catalog stability matters; readable IDs can be practical when a bundle exposes messages directly to its users.

Set and manage the user’s locale

Symfony uses the current request locale to choose a message catalog. A common pattern is a _locale route attribute:

#[Route('/{_locale}/account', name: 'account', requirements: ['_locale' => 'en|fr|de'])]

The locale can also be established from a user’s profile, session, domain, or another request listener. Symfony’s documentation describes the locale as stored on the request and also capable of being stored in the user’s session.

Switching locale for the current request

LocaleSwitcher can change the locale while handling the current request. That change does not automatically persist into a later request, such as one created by a redirect. Persist the preference separately—for example, in the session or user record—and apply it again when the next request starts.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use placeholders instead of concatenation

Do not concatenate changing values into a message before translating it. A generated string such as Hello Alice! will not match a stable catalog entry. Define one message with a placeholder and pass the value separately:

// Resource: translations/messages.en.yaml
hello_user: 'Hello %name%!'
$text = $translator->trans(
    'hello_user',
    ['%name%' => $user->getDisplayName()]
);

Symfony substitutes matching placeholders in the translated result. This keeps the message ID stable and lets translators reorder the name or surrounding words for languages with different grammar.

Handle plural, gender, and locale-sensitive grammar with ICU

Simple %name% substitution does not implement plural rules or other grammatical variants. For count-, gender-, and locale-dependent text, use ICU MessageFormat through PHP’s MessageFormatter. ICU messages use {name}-style placeholders rather than Symfony’s ordinary percent placeholders.

# translations/messages+intl-icu.en.yaml
items: '{count, plural, =0 {No items} one {# item} other {# items}}'
$text = $translator->trans(
    'items',
    ['count' => $itemCount]
);

The +intl-icu suffix in the resource filename tells Symfony to use ICU formatting. See the PHP MessageFormatter documentation for the underlying formatter and syntax. Keep ICU resources distinct from ordinary percent-placeholder resources so translators and the runtime use the same message format.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Fallbacks and missing translations

When a request selects a locale, Symfony loads that locale’s catalog and then uses configured fallback resources for entries that are absent. If the message is still missing, the translator returns the original message ID (or source text when you use real-message IDs). Define fallbacks for languages that should share a base catalog, but still review the missing entries rather than treating the source text as a finished translation.

Install PHP intl for languages beyond English

Current Symfony documentation says its internationalization polyfills allow translation features without PHP’s intl extension, but those polyfills support English translations only. Install and enable PHP intl when your application translates into other languages. Check the requirement against the Symfony and PHP versions deployed by your application, because support details can change between releases.

Find missing and unused messages

Use Symfony’s translation audit command:

php bin/console debug:translation

The command can show missing and unused messages for a locale and domain, helping you locate incomplete catalogs and entries that no code uses. Treat its output as an audit aid, not a complete inventory: extractors may miss messages outside templates unless they are represented with translatable objects or translator calls, and dynamic template expressions are not detected.

Choose a resource format and workflow

Decision Choose this when Important consideration
YAML You want compact, human-readable files that are easy to edit Keep indentation and quoting consistent
XLIFF/XML Your translation team or tooling already works with XLIFF metadata Files are more verbose but can carry richer context
PHP arrays You prefer native PHP resources or generated catalogs Validate syntax and keep executable files trusted
Semantic IDs Source wording changes frequently or many languages share a catalog Document key meaning for translators
Real-message IDs A bundle exposes readable messages or the source text is itself the identifier Wording changes require catalog-wide updates
ICU MessageFormat Plural, gender, or locale-sensitive variants are required Use {name} syntax and +intl-icu resource names

A deployment checklist

  • Install symfony/translation and configure the service.
  • Choose and document a message-ID strategy.
  • Store one resource per supported locale and domain.
  • Set the locale before rendering each request.
  • Pass variable values as parameters; never build IDs by concatenating them.
  • Use ICU resources for plural and other grammatical variants.
  • Provide fallback resources for incomplete locales.
  • Install PHP intl for translations beyond English.
  • Run debug:translation and account for dynamic strings it cannot detect.
  • Verify locale persistence after redirects and other new requests.

For version-specific configuration and loader details, consult Symfony’s current Translations documentation; the page displayed Symfony 8.1 when checked on September 30, 2026, so confirm labels and requirements against the release your application runs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.