Skip to main content

Translations

Every user-facing string — the views, the notification, and the status and error responses (the "we sent a link", "invalid or expired", challenge-failed, and "please wait N seconds" messages) — runs through Laravel's translator under the email-magic-link namespace, so everything follows the application's active locale.

What ships​

LocaleLanguage
enEnglish
deGerman
esSpanish
frFrench
itItalian
nlDutch
ptPortuguese
en-GB, en-USRegional English — delegate to en, ready for regional refinement
pt-PTEuropean Portuguese, in the informal tu form
pt-BRBrazilian Portuguese, in the você form

The regional bundles answer to both spellings: the hyphenated form above and the ISO 15897 form Laravel's documentation prescribes (en_GB, en_US, pt_PT, pt_BR). Set app.locale to whichever your application uses.

An application that distinguishes the regional variants renders fully localized screens and emails with no fallback.

A regional locale the package does not ship reads the bundle of its language: de-AT reads de and fr-CA reads fr, a region nobody listed included. A bundle you publish for the region under lang/vendor/email-magic-link/ wins over its language key by key. This holds for the email-magic-link namespace alone: your application's own translations keep Laravel's lookup, which goes from the locale straight to app.fallback_locale.

Why the identical-looking bundles exist​

en-GB and en-US carry no strings of their own today — they are a one-line require of their base bundle, so there is no second copy to keep in step by hand.

They are the place for the first string that diverges. Without them a visitor on en-GB still reads English, because the package answers a regional locale with the bundle of its language and not with app.fallback_locale.

A visitor on a language the package does not ship reads the strings of app.fallback_locale. If the package has no bundle there either, every text renders as its key, email-magic-link::messages.heading and the like. email-magic-link:doctor reports such a fallback, and an empty one, which a blank APP_FALLBACK_LOCALE leaves behind and which means no fallback at all.

pt-PT and pt-BR diverge, and each carries every string. European Portuguese addresses the reader as tu (Introduz o teu código); the base pt is European Portuguese in the você form (Introduza o seu código); Brazilian Portuguese uses você with its own words and spelling (Digite seu código, Enviamos without the accent).

Translating or rewording​

Publish the language files:

php artisan vendor:publish --tag=email-magic-link-lang

That copies the strings to lang/vendor/email-magic-link/{locale}. Add a locale by copying the en directory — for example to sv — and translating the values. Leave the :app, :minutes, :seconds and :uses placeholders as they are: they are filled in at render time.

One thing on the WireKit screens is not ours to translate​

If you serve the WireKit screens, a few strings on them come from WireKit rather than from this package: the alert prefixes a screen reader announces (Success, Error) and the per-box label on the one-time-code field (Digit :position of :total). All three are screen-reader-only, which is why nothing looks wrong — a sighted reader sees a fully translated page while someone tabbing through the code field hears Digit 1 of 8, Digit 2 of 8, in the middle of an otherwise translated sign-in screen.

Seven locales need nothing. WireKit ships de, es, fr, it, nl, pt and pt-BR beside en (German since 2.26.0, the other six since 2.27.0) and registers them at boot, so an application on one of those locales gets these strings translated with no publishing step and no file of its own.

Two details decide whether that reaches you:

  • The locale has to match exactly. Laravel's JSON loader looks for the locale as written, with no fallback to the base language, so de is served and de_DE, de-AT and de-CH are not. On a regional locale, supply the strings yourself as below.
  • Your own file wins per key, not per file. Application-level translations are merged over the package's, so defining one key leaves every other WireKit string at its shipped value. You never lose a bundled locale by adding a file — only by overwriting the keys in it.

For a locale WireKit does not ship — Swedish, say — publish the reference catalog and copy the closest one to your language root:

php artisan vendor:publish --tag=wirekit-lang
cp lang/vendor/wirekit/en.json lang/sv.json

Then translate the values in lang/sv.json. Leave the :position and :total placeholders in place. Do not copy en.json over a locale WireKit already ships — that replaces working translations with English until you have retranslated every key by hand. The shipped set is the list of files in vendor/pushery/wirekit/lang.

The email itself​

The notification is a normal Laravel notification. To change more than its wording — its branding, its channels, its layout — extend MagicLinkNotification and point the notification config key at your class. See Extension points.

To name a tenant instead of app.name, or to greet the recipient by name, a subclass is not needed: point mail_identity at a class implementing MailIdentity. See Name the tenant and greet by name.