Upload the source catalogs
Choose YAML, XLIFF or PHP resources from translations/. Keep messages, validators, security and custom domains separate, just as they are in your repository.
Symfony Translation Component
Translate the words. Keep the contract. Translate Symfony YAML catalogs, XLIFF files and PHP message arrays with human-level AI accuracy. Every parameter, choice boundary and translation domain stays protected.
trans
YAML · XLIFF · PHP
Legacy choices + ICU
A string is part of your application
A generic AI translator turns %name% into %nom%. A bracket disappears from a plural rule. YAML indentation shifts. The French reads well; the application doesn’t.
That’s how a localization task becomes an InvalidMessageCatalogueException, a failed container or cache compilation, or a Twig view that prints a raw placeholder. Someone on your team ends up tracing a production bug back to a translation file.
Your Symfony translation tool should know the difference between language and logic.
welcome: 'Hello %name%'
welcome: 'Bonjour %nom%'
welcome: 'Bonjour %name%'
Syntax protection, before translation
Percent signs and range brackets aren’t punctuation to clean up. They’re executable meaning. Qopywriter’s Symfony localization AI separates translatable text from protected syntax, then checks the exported catalog against the original contract.
%count% and %name% keep their spelling and case. Their position follows the translated sentence’s grammar.
Native resources, not flattened text
Translate Symfony messages files without rebuilding your translation setup. Qopywriter preserves the resource format, message keys and domain boundaries your PHP application already relies on.
{{ 'account.welcome'|trans({'%name%': name}, 'messages') }}
account:
welcome: 'Bonjour %name%'
billing:
issue_invoice: 'Émettre une facture'
cart:
quantity: 'Quantité : %count%'
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2"
xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="fr"
datatype="plaintext" original="messages">
<body>
<trans-unit id="account.welcome"
resname="account.welcome">
<source>Hello %name%</source>
<target>Bonjour %name%</target>
</trans-unit>
</body>
</file>
</xliff>
<?php
return [
'account.welcome' =>
'Bonjour %name%',
'billing.issue_invoice' =>
'Émettre une facture',
'cart.quantity' =>
'Quantité : %count%',
];
Language quality, beyond a valid schema
Your billing screen isn’t a dictionary exercise. “Issue” is a verb on an invoice button, not a support problem. Qopywriter reads message context and enterprise PHP terminology to deliver human-level linguistic accuracy across your application.
Short labels stay sharp. Validation messages explain the fix. And localized sentences follow the target language’s word order, gender and plural forms, without renaming the variables that drive them. The result sounds like one product, not a collection of unrelated translations.
billing.issue_invoice
PHP translation management for Symfony teams
File-based localization. No extra translator service in your runtime, and no new Twig conventions to teach the team.
Choose YAML, XLIFF or PHP resources from translations/. Keep messages, validators, security and custom domains separate, just as they are in your repository.
Select the target language. The AI reads message context, protects parameters and pluralization rules, then validates the serialized resource. Human-readable text changes. Your application contract does not.
Return localized files to translations/. Keep Symfony’s domain.locale.loader naming, review the changed values and run your application checks before merging.
A release check, not a leap of faith
Lint the resources, inspect missing messages and warm the production cache. Then exercise your Twig views with zero, one and many values. Your existing Symfony pipeline remains the final release gate.
Symfony Translation component docs# Validate resource syntax
php bin/console lint:yaml translations/
php bin/console lint:xliff translations/
php -l translations/messages.fr.php
# Inspect catalog coverage and compile the cache
php bin/console debug:translation fr --domain=messages
APP_ENV=prod APP_DEBUG=0 php bin/console cache:warmup
Catalog translation, predictable pricing
Every plan includes AI translation, parameter shielding and catalog structure protection. Test a real Symfony catalog with the free trial.
For a focused application.
400,000characters per month
For regular release cycles.
1,000,000characters per month
For engineering teams and agencies.
3,000,000characters per month
For a full year of localization.
12,000,000characters per year
Developer questions
File formats, plural rules, translation domains. Here’s what stays under your control.
Ask about your Symfony workflowTranslate YAML (.yaml and .yml), XLIFF (.xliff and .xlf) and PHP array catalogs. That includes messages.fr.yaml, validators.de.xliff and security.es.php. Message keys, resource structure and translation domains stay protected; human-readable values are localized.
No. Their spelling, case and percent delimiters are locked. A translated sentence can move the same token to fit the target language's word order, but %name% never becomes %nom%. The exported message retains the original parameter set.
The two grammars stay separate. Symfony’s legacy MessageSelector uses patterns such as {0} No items|{1} One item|]1,Inf[ %count% items. Current ICU resources use {count, plural, =0 {No items} one {One item} other {# items}} in a catalog such as messages+intl-icu.fr.yaml.
Qopywriter protects the selectors, delimiters and parameter names in each format. It preserves your pluralization system without converting legacy choices into ICU. See Symfony’s ICU MessageFormat reference for the current formatter grammar.
The tool prevents translation-induced catalog damage: malformed resource structure, altered interpolation tokens and broken choice delimiters. Schema and syntax protection keep these regressions out of the exported resource.
Your application’s checks validate that resource against its configured loaders and formatter. Run lint:yaml or lint:xliff, inspect debug:translation and warm the production cache before merging. This catches application-level configuration problems as well as missing messages.
Yes. Message IDs and domains stay unchanged. Keep filenames in domain.locale.loader form and place the translated resources in translations/. Existing trans() calls and Twig trans filters resolve the same keys.
Your Symfony application continues to control locale selection and fallback configuration. This is a file-based Symfony i18n localization tool, not a replacement for the Translation component.
Context does the work. Message keys, neighboring strings and available translation context help distinguish an invoice action from a support issue, or an application role from a job title. The AI maintains consistent enterprise terminology and UI tone while handling the target language’s grammar.
Technical protection and linguistic quality are separate jobs. Qopywriter handles both: natural message values inside a protected catalog structure.
Yes. Each version keeps its own schema. Namespaces, unit IDs and inline code references remain protected while target text is translated. Source segments stay available for review, and target-language metadata identifies the output locale.
Yes. Start with the free trial and a representative catalog containing parameters, plural messages and your own domains. Compare the translated file, load it in your application and run your release checks. Paid plans start at $9 per month.
Start with one catalog. Translate a target locale, inspect the diff and run your cache warmup. Ship language your customers understand, with syntax your application still recognizes.