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
| Locale | Language |
|---|---|
en | English |
de | German |
es | Spanish |
fr | French |
it | Italian |
nl | Dutch |
pt | Portuguese |
en-GB, en-US | Regional English — delegate to en, ready for regional refinement |
pt-PT | European Portuguese, in the informal tu form |
pt-BR | Brazilian 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
deis served andde_DE,de-ATandde-CHare 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.