Laravel localization in German Deutsch

Everything you need to ship German in a Laravel app: the right locale codes, the exact plural forms trans_choice() expects, real localized Carbon output and Latin-script considerations. Every value on this page was generated by running ICU, CLDR and Carbon — not copied from another article.

ISO 639-1

de

Script / Direction

Latin · LTR

Plural forms (Laravel)

2

Text vs English

Expands

Locale codes

Set the base locale in config/app.php. For regional variants, German commonly uses: de_DE, de_AT, de_CH, de_LU

// config/app.php
'locale' => 'de',
'fallback_locale' => 'en',

// Or switch at runtime
App::setLocale('de');

Plural rules: what German actually needs

CLDR defines 2 cardinal categories for German. The sample numbers below were computed by ICU for this exact locale:

CLDR category Numbers that select it
one 1
other 0, 2–130, 200, 1000, 1000000, 1.5

Laravel's trans_choice() maps numbers to 2 pipe-separated forms for this locale:

Form index Numbers that select it
0 1
1 0, 2–130, 200, 1000
// lang/de/messages.php
'items' => ':count item|:count items'

// Usage
trans_choice('messages.items', $count, ['count' => $count]);

Try any number live in the pluralization tester.

Localized dates with Carbon

Real output for German (de locale), generated by Carbon for March 21, 2026:

$date = now()->locale('de');

$date->translatedFormat('l, j F Y');
// "Samstag, 21 März 2026"

$date->isoFormat('LLLL');
// "Samstag, 21. März 2026 14:30"

$date->isoFormat('L');
// "21.03.2026"

$date->subDays(3)->diffForHumans();
// "vor 3 Monaten"

What to watch out for in German

Why German breaks layouts that survive every other language

German is the language that exposes hardcoded widths. Translated German runs roughly thirty per cent longer than English on average, and short interface strings are far worse than the average suggests — the shorter the English, the larger the expansion ratio. A button reading "Save" becomes "Speichern", "Edit" becomes "Bearbeiten", and "Settings" becomes "Einstellungen".

English German Growth
Save Speichern +125%
Edit Bearbeiten +150%
Cancel Abbrechen +80%
Settings Einstellungen +63%
Search Suchen +17%
Undo Rückgängig machen +375%

Compounding makes it worse. German forms new nouns by welding existing ones together rather than separating them with spaces, so concepts that are three words in English become one unbreakable token. Zahlungsbedingungen (payment terms), Benutzerkontoeinstellungen (user account settings) and Geschwindigkeitsbegrenzung (speed limit) cannot wrap at a space because there is no space in them.

The practical consequence is that a fixed-width container which fits every Romance language will still overflow in German, and the overflow will be a single long word rather than a graceful second line. Test German early rather than treating it as one more locale at the end.

Let long compounds break instead of overflowing

<!-- Tailwind -->
<span class="hyphens-auto break-words" lang="de">
    Benutzerkontoeinstellungen
</span>

<!-- The lang attribute is required: hyphenation
     rules are language-specific and the browser
     needs to know which dictionary to apply. -->

The lang="de" attribute is not decorative. Without it, hyphens: auto has no dictionary to work from and silently does nothing, which is why hyphenation often appears broken in multilingual apps.

Du or Sie: a decision you cannot postpone

German distinguishes formal and informal address grammatically, and the choice runs through every sentence that speaks to the user. This is not a stylistic preference you can settle later — it changes pronouns, possessives, verb conjugations and imperatives, so switching afterwards means retranslating essentially all of your interface copy.

Informal (du) Formal (Sie)
You du Sie
Your account dein Konto Ihr Konto
Save your changes Speichere deine Änderungen Speichern Sie Ihre Änderungen
Log in Melde dich an Melden Sie sich an
Do you want to continue? Willst du fortfahren? Möchten Sie fortfahren?

The convention splits by market. Consumer products, startups and anything targeting a younger audience overwhelmingly use du — it is now standard for German-language SaaS. Banking, insurance, healthcare, government and most B2B enterprise software use Sie, and using du there reads as presumptuous rather than friendly.

Note that formal Sie and its possessive Ihr are always capitalised, in any position in the sentence. That capital is what distinguishes Sie (formal you) from sie (she, or they), so a translator lowercasing it changes the meaning rather than just the style.

Record the decision somewhere your translators will see it, ideally as a note attached to the locale itself. The most common way a German translation ends up inconsistent is two translators working on different features a few months apart, each making their own reasonable choice.

Cases and gender make concatenation impossible

German nouns carry one of three grammatical genders — masculine, feminine or neuter — and the language inflects for four cases. Together these determine the form of articles, adjective endings and pronouns, and they make the common English habit of building sentences from fragments completely unworkable.

The definite article alone has six distinct forms depending on gender and case:

Case Masculine Feminine Neuter Plural
Nominative der die das die
Accusative den die das die
Dative dem der dem den
Genitive des der des der

So a template like "Delete the " . $type cannot work. "Delete the file" is Die Datei löschen, "delete the user" is Den Benutzer löschen, and "delete the project" is Das Projekt löschen. The article changes with the noun, and no amount of clever string building will get it right.

Wrong — assembles a sentence from parts

// This cannot be translated correctly into German
__('actions.delete_the') . ' ' . __("types.{$type}")

// Produces: "Löschen die Benutzer" — wrong article, wrong order

Right — one complete key per message

// lang/de/actions.php
return [
    'delete_file' => 'Die Datei löschen',
    'delete_user' => 'Den Benutzer löschen',
    'delete_project' => 'Das Projekt löschen',
];

Gender is also not predictable from meaning. Das Mädchen (the girl) is neuter, because the diminutive suffix -chen always is. Translators know this; string concatenation does not.

Capitalisation and the ß character

German capitalises every noun, not just proper nouns. Der Benutzer speichert die Datei capitalises both Benutzer and Datei because both are nouns. This is a hard orthographic rule rather than a style choice, so applying English title-case or sentence-case transformations to German strings produces text that reads as misspelled.

That has a direct implication for CSS. A text-transform: capitalize or uppercase applied globally will mangle German, and text-transform: lowercase is actively wrong because it strips the capitals the language requires. Scope those rules so they do not apply to German text.

The ß character (Eszett or sharp s) is the other orthographic trap. It exists in Germany and Austria but not in Switzerland, where it is always written as ss. So Straße in Germany is Strasse in Switzerland, and a Swiss user seeing ß registers it as a foreign spelling.

When uppercasing, ß traditionally becomes SS, which means uppercase transformations are not reversible: STRASSE could be Straße or Strasse. A capital exists and was formally accepted in 2017, but support is inconsistent enough that most style guides still prefer SS.

If you serve Switzerland, treat de_CH as its own locale rather than an alias for de_DE. The ß difference alone is enough for Swiss users to notice, and Swiss German also uses different quotation marks and thousands separators.

Plurals look simple and hide a trap

German takes two plural forms, exactly like English, so trans_choice() works with a straightforward two-part string. That simplicity is real but it conceals a genuine difficulty: German plural noun formation is highly irregular, and the noun itself changes in ways translators must handle per word.

Singular Plural Pattern
das Bild (image) die Bilder add -er
der Benutzer (user) die Benutzer no change
die Datei (file) die Dateien add -en
das Konto (account) die Konten irregular
der Ordner (folder) die Ordner no change
das Formular (form) die Formulare add -e

Notice that several plurals are identical to their singular. Der Benutzer and die Benutzer differ only in the article, so a string that drops the article becomes genuinely ambiguous — :count Benutzer reads correctly for any number, but a bare Benutzer label could mean one or many.

The zero case also differs from English convention. German normally uses the plural form with keine: keine Dateien rather than keine Datei. Since Laravel maps zero to the "other" form for German, this works by default — but only if the translator wrote the plural form there rather than copying the singular.

Numbers, dates and the three German markets

German-speaking Europe is three markets with different conventions, and treating them as one locale produces numbers that look subtly wrong to two thirds of your users.

Germany (de_DE) Austria (de_AT) Switzerland (de_CH)
Thousands 1.234.567 1.234.567 1'234'567
Decimal 1234,56 1234,56 1234.56
Currency 1.234,56 € € 1.234,56 CHF 1'234.56
Date 21.03.2026 21.03.2026 21.03.2026
January Januar Jänner Januar

The decimal comma is the one that causes real bugs. A German user typing 1234,56 into a price field submits a string that floatval() reads as 1234, silently discarding the cents. Parse localised numeric input explicitly rather than relying on PHP's default coercion.

Austrian month names differ from German ones for January and February — Jänner and Feber rather than Januar and Februar. Carbon handles this when given the right locale, which is a good reason to pass de_AT rather than falling back to de.

Dates are written day-first with dots and, in the long form, a full stop after the day number: 21. März 2026. That trailing dot is an ordinal marker rather than punctuation, and omitting it is a common tell that a date was formatted by English-centric code.

What ships broken most often

Two of these are worth catching automatically. A test that renders every German string into a fixed-width container and flags overflow costs an afternoon to write and finds truncation before users do. A grep for concatenation — any __() call adjacent to a string join — finds the sentences that can never be translated correctly, and it finds them at the point where they are cheap to restructure.

The formality decision deserves a written home rather than a shared assumption. A single line in your translation brief stating that the product uses du or Sie, with one worked example, prevents the drift that otherwise accumulates every time a new feature is translated by someone who was not there for the original conversation.

German is a useful first target precisely because it is demanding. An interface that survives German compounds, case agreement and the formality decision will usually absorb Dutch, the Nordic languages and most of Slavic Europe without further layout work.

Framework strings already translated

Laravel's own validation, auth and pagination strings are maintained in German by the open-source Laravel-Lang project (MIT). Install them, then manage your app's own strings live:

composer require laravel-lang/common --dev
php artisan lang:add de
php artisan lang:update

Translate your app into German today

Import your lang files, translate every key into German with one AI click, and publish changes live — no deploy. Set up in 5 minutes.

We use cookies to improve your experience and analyze site traffic. Cookie Policy

Cookie Preferences

Essential

Required for the site to work

Analytics

Help us improve the site

Marketing

Personalized ads and content