Translate a Symfony App into German
Upload your Symfony catalogue, such as <code>translations/messages.en.xlf</code> or <code>.yaml</code>. Manuce translates the values into German, checks every <code>%name%</code> and <code>{name}</code> placeholder, and returns the same file, ready to drop back into your project. Two things remain for you to check: long German compounds in your layout, and plurals written with the legacy interval syntax.
What it costs
For the language files of a Symfony app totalling about 3,000 words, into German:
To understand, internal use.
Ready to send, by the technical specialist.
Cross-checked. For documents that commit you.
Price for one language, original layout included. VAT not applicable — article 293 B of the French General Tax Code (CGI). The exact quote, based on your file's word count, is shown before you pay.
How German affects your Symfony messages
German uses the Latin alphabet, but it is hard on interfaces. Nouns fuse into long compounds: Account settings becomes Kontoeinstellungen, and Order confirmation becomes Bestellbestätigung. German text typically runs 20 to 35% longer than English. A button sized for Save may cope with Speichern, while one sized for Confirm can overflow with Bestätigen.
- Capitals: every noun is capitalised, even mid-sentence, as in
Ihr Passwort wurde geändert. - Form of address: business software uses formal Sie (Melden Sie sich an). Some consumer apps prefer informal du. Decide before translating, then keep the same choice across every domain, including
messages,validatorsand emails. - Punctuation: German quotation marks look „like this“, and there is no space before a question mark or colon.
- Hyphenation: with
lang="de"on the html element of your Twig base template, CSShyphens: autolets the browser break long compounds cleanly.
Plurals: two forms, with their own rules
German has two CLDR plural categories, one and other. The one category covers exactly 1, so zero takes the plural: 0 Dateien. This matches English, but not every source language works this way. French, for instance, treats 0 as singular.
With ICU messages, the rule is applied at runtime. Writing {count, plural, one {# Datei} other {# Dateien}} is enough, and the Intl component selects the correct form for the de locale.
With the legacy pipe syntax, the intervals are hard-coded in the string. A source written as {0,1} %count% file|]1,Inf[ %count% files keeps its bounds after translation and will display "0 Datei". Translation does not alter these intervals. In the German file, rewrite them as {0} Keine Dateien|{1} Eine Datei|]1,Inf[ %count% Dateien, or move those messages to ICU.
What Manuce returns, and what it does not do
You upload messages.en.xlf or messages.en.yaml and get back the same file in the same format. For example, cart.summary: "%count% items in your basket" becomes cart.summary: "%count% Artikel in Ihrem Warenkorb", with the key and placeholder unchanged.
- Only the values change. Indentation, key order, quotes, comments, line endings, encoding and BOM are preserved.
- Every translated value is compared with its source, including variables and tags. If a mismatch persists, the source value is kept and the report says so.
- The following are left untranslated: keys, empty values, URLs, email addresses, numbers, colours, date formats, identifiers and anything you mark as non-translatable.
- A report comes with the file, listing the strings translated and those left as they were, with the reason for each.
Manuce translates only what is in the file you upload. It does not touch strings hard-coded in Twig templates or controllers, does not fix plural intervals and does not resize your layout. It does not provide sworn or certified translation either, so terms and legal notices intended for Germany should be reviewed by a lawyer. Pricing counts the words in values only, excluding keys and tags, and German is charged at the base rate.
Preparing the project and checking the result
Before you upload:
- Run
php bin/console translation:extract --force en(using your source locale). This collects every string passed through the|transfilter or the translator service into the catalogue. - Skip Symfony's own messages. The Validator and Security components already include German translations, so in
validators.en.xlfonly your custom constraint messages need translating. - Mark brand, product and plan names that must stay as they are as non-translatable.
After delivery:
- Save the file as
translations/messages.de.xlf(or.yaml) and adddetoenabled_locales. - Clear the cache, then run
php bin/console debug:translation deto find missing messages. - Check your densest screens (navigation, buttons, data tables, transactional emails) for truncated German labels.
- Read the report: a value left in the source language usually points to a malformed placeholder in the original.
In practice
- Run the message extraction so the source catalogue is complete.
- Upload messages.xx.xlf or .yaml: you get an instant quote and a free translated sample paragraph.
- Choose a translation level and pay for the order.
- Download the file and report, then save the file as translations/messages.de.xlf or .yaml.
- Enable the de locale, clear the cache and check long labels on screen.
Frequently asked questions
Will my %name% and {count} placeholders survive?
Yes. Each translated value is checked against the source, including placeholders and tags. If a mismatch persists, the source value is kept and flagged in the report, so a broken message never reaches production.
Do I need to translate the validators and security domains?
Only your own entries. Symfony already provides German translations for its built-in validation and security messages. Upload just the messages you added yourself.
Why does my app show "0 Datei" instead of "0 Dateien"?
Your message probably uses the legacy interval syntax with a bound such as {0,1}, inherited from the source language. In German only 1 takes the singular. Fix the intervals in the German file or switch the message to ICU format.
Will dates and numbers appear in German format?
Date formats and numbers in the file are not translated. German display (31.12.2025, 1.234,56) comes from the active locale and Twig's Intl filters, not from the translation catalogue.
Will longer German text break my layout?
It can: German often runs 20 to 35% longer than English, and compounds do not wrap on their own. Use flexible button widths, set lang="de" with hyphens: auto, and review dense screens after integrating the file.
The specialist in charge
This subject goes to Dédale, the technical specialist. See how it works.
The same file, into another language
Into German, other files
See also
Try it on your own file, free
A sample of your file translated at the level you choose, before any payment. You judge, then you decide.