Skip to main content
WireKit
Copy for LLM

Localization

Every user- and screen-reader-visible string WireKit renders itself — Close, Next, Uploading, Add to cart, the pagination summary, the "is typing…" announcement — runs through Laravel's __() translation helper. Out of the box everything reads in English and nothing breaks. To ship another language you translate those keys.

The key shape: wirekit:: + the English text

Every key WireKit ships carries a wirekit:: prefix. Close is wirekit::Close, Add to cart is wirekit::Add to cart. The prefix is part of the key, not a separate namespace — Laravel's JSON channel has no namespaces, so this is a naming convention inside the one flat catalog, and it works because the translator looks a key up verbatim before doing anything else with it.

It exists because that catalog is shared with yours. Without a prefix, a common English word means one thing in your application and another in a component, and there is only one place to put it:

// lang/de.json — before the prefix, this ONE entry answered for both.
{
    "Map": "Karte"
}

If your Map is the verb "to map" and WireKit's is the noun on a map component, your wording wins — inside our component, where it is wrong. Nothing throws and nothing logs; only the text is wrong. Reported from a real application with four such collisions, one of them on Dismiss across every alert on the site. With the prefix, Map and wirekit::Map are two strings, and yours cannot reach into a component that never asked for it.

php artisan wirekit:verify names any collision it finds, so you do not have to go looking.

Your existing catalog keeps working If you translated WireKit's strings before the prefix existed, your file still says "Close" and nothing says "wirekit::Close". Those translations keep applying, so renaming can wait — see Upgrading a catalog written before the prefix.

What this covers. Only the strings WireKit hard-codes. Text you pass into a component (labels, slot content, your own copy) is yours to translate however your app already does. This page is about the handful of built-in words WireKit adds on your behalf.

Languages WireKit already speaks

Seven locales ship today: English, German, Spanish, French, Italian, Dutch and Portuguese. Set your application's locale to any of them and the built-in strings follow — no publishing step, no configuration:

// config/app.php — or wherever your application decides its locale.
'locale' => 'de',

Anything WireKit renders on your behalf is then German; anything you pass in is still yours.

If a phrase does not fit your product's voice, publish the catalog and edit your copy (see below) — your file wins per key, so you can change one word and leave the rest.

Any locale beyond those seven is the walk-through further down, which is short: the reference file lists every key that exists, and a completeness guard on our side means the list is never out of date with the components.

Regional locales

A regional locale resolves through its base language automatically. Set pt-PT, de-AT, de-CH, es-MX or fr-CA and WireKit's strings come from the Portuguese, German, Spanish or French catalog — nothing to configure, no extra file to add, and the same for every other regional variant of a language above.

Where a regional catalog of its own exists, it is layered on top of that base rather than replacing it: pt-BR takes the Brazilian wording for the phrases the two varieties spell differently and keeps the shared Portuguese for everything else. Which variety each catalog is written in lists them.

// config/app.php — a regional locale needs no catalog of its own.
'locale' => 'pt-PT',

Both separators are the same locale here: pt-BR and pt_BR resolve identically, down to the regional catalog. PHP's own locale primitives emit the underscore form, so it is what you get from Locale::getDefault() and a common value to find in a config/app.php — it needs no special handling on your side.

Your own file still wins per key. If your app ships lang/pt-PT.json, every key it defines overrides WireKit's Portuguese and every key it leaves out still arrives from the base catalog — so you can reword one regional phrase without re-translating everything around it.

This covers the catalogs WireKit ships. How your application's own lang/pt.json behaves for a pt-PT visitor is unchanged, and stays your decision.

A word you deliberately left untranslated will change when WireKit learns a language

The section above is about what happens when you define a key. This is the reverse, and it is the one that surprises people on an upgrade.

If your app has no catalog entry for a key, WireKit's own catalog answers — and the answer depends on which languages WireKit speaks at that moment. Leaving a key undefined because you want the English word is therefore not a decision that holds: it holds only until a release adds your visitor's language, and then the same page renders a translation you never asked for.

That is a real report, not a hypothetical. An application ran a plan tier named Unlimited — a proper noun, not a quantity — and relied on the absence of a catalog entry to keep it English. It stayed English through every locale WireKit did not yet speak, and became Unbegrenzt for German visitors in the release that added German.

Absence is not an override. If you want a word held fixed, say so:

{{-- 1. The tier is called "Unlimited" — a name, so it reads the same in every language. --}}
{{-- 2. Without this prop the word goes through the translator, which is correct when it --}}
{{--    describes a quantity and wrong when it is the name of the thing. --}}
<x-wirekit::usage-meter label="Seats" :used="42" :limit="null" unlimited-label="Unlimited" />

Components that render a word which might be a name take an override prop for exactly this — unlimitedLabel on Usage Meter is the worked example. Reach for the prop rather than for a catalog entry: a catalog entry has to win against WireKit's translation on every locale you support, and you have to remember it again the next time you add one. The prop does not care how many languages either side speaks.

Which of the two you want Use a catalog entry when you disagree with a translation — you want a different German word. Use the prop when the string is not language at all: a brand, a plan name, a product tier. The first is an opinion about wording; the second is a statement that the value has no wording.

Which variety each catalog is written in

A base-language catalog has to pick a variety, and the choice reaches every regional locale that resolves through it. Stated here so you can decide deliberately rather than inherit it:

Catalog Variety Reaches
pt European Portuguese pt, pt-PT
pt-BR Brazilian Portuguese pt-BR, pt_BR
de Standard German de, de-AT, de-CH, …
es European Spanish es, es-MX, es-AR, …
fr Metropolitan French fr, fr-CA, fr-BE, …
nl Netherlands Dutch nl, nl-BE
it Standard Italian it, it-CH
en every English locale

Brazilian Portuguese has its own catalog, because the distance from European Portuguese is wide enough to read as a mistake: a Brazilian reader expects Carregando rather than A carregar, aba rather than separador, tela rather than ecrã. It holds only the strings the two varieties spell differently — everything else arrives from pt, so the shared wording stays in one place.

The other rows are single catalogs on purpose: the distance between the varieties there is small enough that no reader is addressed in the wrong language. Where you disagree for your product, the paragraph above applies — your own lang/{locale}.json wins per key, and you restate only the strings you want to change.

How the translations address the reader

The shipped catalogs are informal. German uses du/dein, Spanish tú/tu, French tu/ton, Italian tu/tuo, Dutch je/jouw, Portuguese tu/teu. English draws no such distinction, so it is unaffected.

This is worth knowing before you set a locale, because WireKit's words sit inside your copy rather than beside it: a product written in a formal voice would read as itself until a rollback message says du.

Changing it is small and does not mean re-translating anything. Only a handful of keys per catalog carry a pronoun at all — the optimistic-rollback messages and the word You. Publish the catalog, copy the locale file into lang/{locale}.json, and restate just those keys; every key you leave out keeps arriving from WireKit, so nothing else moves.

The key reference

WireKit ships lang/en.json — the complete, generated list of every string key its components emit, each mapped to its English text. This is your reference: it is exactly the set of keys you can translate, nothing more to hunt for.

Publish a copy into your app to work from:

# 1. Copy WireKit's shipped catalogs into your app's lang directory.
#    Lands at lang/vendor/wirekit/{en,de,es,fr,it,nl,pt}.json — references to copy from,
#    not files WireKit reads back. Editing them in place changes nothing.
php artisan vendor:publish --tag=wirekit-lang

Adding a locale

Laravel's JSON translation loader matches on the key, so a translated file in your app's own lang/ directory overrides WireKit's English per key — no configuration, no per-package wiring.

# 2. Create a locale file named for the target locale (German shown here).
#    It lives in your app's lang/ root, NOT under vendor/ — that is where
#    Laravel looks first, so your values win over WireKit's English.
cp lang/vendor/wirekit/en.json lang/de.json
// 3. lang/de.json — translate the VALUES, keep the keys verbatim.
//    The wirekit:: prefix is part of the key: drop it and the entry
//    no longer answers, because the lookup asks for the whole string.
//    Untranslated keys fall back to their English text, so you can
//    translate incrementally; there is no all-or-nothing requirement.
{
    "wirekit::Close": "Schließen",
    "wirekit::Next": "Weiter",
    "wirekit::Previous": "Zurück",
    "wirekit::Add to cart": "In den Warenkorb",
    "wirekit::Out of stock": "Ausverkauft"
}

Copying the reference gives you the prefixed keys already, which is the whole reason to start from it rather than typing them out.

Set your app's locale as usual (app()->setLocale('de'), or your locale middleware) and WireKit's strings follow.

Placeholders and pluralization

Some keys carry placeholders or plural forms. Keep the placeholder tokens (:current, :last, :page, :total, :count, :status, :n) exactly as they appear — only the words around them are yours to translate.

// 4. Placeholder keys: move the :tokens to where your grammar needs them,
//    but never rename or drop them.
{
    "wirekit::Page :current of :last": "Seite :current von :last",
    "wirekit::Showing :first to :last of :total results": ":first bis :last von :total Ergebnissen",
    "wirekit::Go to page :page": "Zu Seite :page"
}
// 5. Pluralization keys use Laravel's pipe syntax (trans_choice). Preserve
//    the {0} / {1} / [2,*] range markers; translate only the phrases.
{
    "wirekit::{0} no reactions|{1} :count person reacted|[2,*] :count people reacted": "{0} keine Reaktionen|{1} :count Person hat reagiert|[2,*] :count Personen haben reagiert"
}

Upgrading a catalog written before the prefix

WireKit's own catalog still answers a plain __('Close') your application makes on its own behalf, underneath anything you define yourself. Registering this package's language directory always had that effect — its keys were ordinary English words, so a template of yours calling __('Close') got a translation you never wrote — and the prefix does not take it away. It is a fallback and never a decision: your own entry for a key still wins, exactly as it did before.

If you translated WireKit's strings before the prefix existed, your catalog is full of entries like "Close": "Schließen" and says nothing about wirekit::Close. Those translations still apply. WireKit reads a plain entry as an override of the matching prefixed key, so the release that renamed the keys does not take your wording away.

Nothing is required of you. When you want to move, move one key at a time:

// 6. lang/de.json — mid-migration, and both spellings are fine here.
//    The prefixed entry is what WireKit reads. The plain one is now yours
//    alone: it no longer reaches any component, so it is free for your own
//    use, and can go if nothing in your app asks for it.
{
    "wirekit::Close": "Schließen",
    "Close": "Fenster schließen"
}

The prefixed key always wins where you have written one — an explicit choice outranks the plain-key inference — so adopting a key is never blocked by the old entry still being there. php artisan wirekit:verify lists any key you have in both spellings, which is the moment to decide whether that is deliberate.

Turning the compatibility off

The plain-key fallback is a config switch. Turn it off and WireKit uses its own wording everywhere except the keys you have prefixed:

// config/wirekit.php
'translations' => [
    'legacy_key_bridge' => env('WIREKIT_LEGACY_TRANSLATION_KEYS', true),
],

Reach for it when a plain key of yours collides with one of ours and you would rather give the components their own wording back than rename anything. Everything you have written with a wirekit:: key keeps applying — the switch only governs the inference from the unprefixed ones.

This compatibility is temporary The plain-key fallback exists to carry catalogs across the rename, and it is removed in the next major version — by then your keys must carry the prefix, or the translations behind them stop applying. Prefixing them is the migration; the switch above is how you check you have finished, because with it off nothing is inferred and any string that reverts to WireKit's wording is one still waiting to be moved.

How it stays complete

The key reference is guarded against drift: a WireKit release can never add a built-in string without adding its key to lang/en.json, so the file you translate is always the full set. When you upgrade WireKit and new keys appear, re-run the publish above and diff lang/vendor/wirekit/en.json against your locale file to see exactly which new strings need a translation.

lang/en.json also does a second job now that the keys carry a prefix. It is the English backstop: a key that no catalog answers used to fall through to the key itself and render readable English, and under a prefix that same fall-through would render wirekit::Close. So the English catalog sits underneath every locale, and a visitor on a language WireKit does not speak reads English, exactly as before.

Was this page helpful?

Voting requires cookies or local storage. What we store