A localization component your app uses to translate its copy into multiple languages — detect a language, look up translated strings, and let visitors switch between languages.
ForgeLanguage is a component that adds multi-language support to your app. It figures out which language a visitor should see, loads that language's copy from simple PHP files, and gives your views small helpers to fetch translated strings. Everything lives in your app's structure, so your copy is just data you control — no language machinery leaking into your business code.
Prerequisite: ForgeLanguage is built on the routing layer (it hooks the request to read the active language), so it needs the router capability to be present in your app.
Use ForgeLanguage whenever the same screen needs to read differently for different visitors — a storefront in English and Spanish, an admin panel for a region, or marketing pages matched to a visitor's browser. It's the piece that answers "which language am I showing?" and "what's this label in that language?"
It doesn't dictate how you organize your copy — you define that. ForgeLanguage just resolves it per request and hands it back.
php forge.php package:install-module --module=ForgeLanguage
Registering the module wires the language service into your container and loads its helper functions, so they're available anywhere in your app.
Your copy lives in your app's
languages directory — one PHP file
per language, returning an array of keys. Group
related strings under dotted keys, and read the
nested value back with the same key:
// app/languages/en.php
return [
'welcome' => 'Welcome to Forge Kernel',
'nav' => [
'home' => 'Home',
'billing' => 'Billing',
],
];
// app/languages/es.php
return [
'welcome' => 'Bienvenido a Forge Kernel',
'nav' => [
'home' => 'Inicio',
'billing' => 'Facturación',
],
];
A missing key returns your
fallback — or the key itself — so
your app never surfaces a blank label. If a need
arises, terms can also come from discrete file
paths or from a module's language directory,
keeping larger apps organized.
For each request, ForgeLanguage decides the active language in a predictable order — the first supported one it finds wins:
?lang= query parameter.language cookie.Accept-Language.Choices made via the query parameter or the switcher are remembered in the session, so the preference sticks across pages.
In your views, use the global helpers. Each one resolves against the current language by default:
echo languageTerm('nav.home', fallback: 'Home');
echo languageTerm('welcome', fallback: 'Welcome', args: ['name' => 'Sam'], language: 'es');
$current = current_language(); // e.g. 'en'
$languages = available_languages(); // the configured language list
$url = language_switcher_url('es'); // switch-to-Spanish URL
languageTerm() — a translated
string, with a fallback, argument
substitution, and an optional override
language.
current_language() — the active
language code.
available_languages() — the
configured languages with their labels and
flags.
language_switcher_url() — a URL
that switches to another language.
Configure which languages you support and which is the default through the module's config:
return [
'forge_language' => [
'languages' => [
'en' => ['label' => 'English', 'flag' => 'EN'],
'es' => ['label' => 'Español', 'flag' => 'ES'],
],
'default' => 'en',
],
];
The default is the language used when
nothing else matches. Any key in
languages with a matching translation
file becomes selectable.
To let visitors pick a language, render the included switcher component in your view. It shows each language's flag and label, marks the current one, and links to the right switch URL:
use Modules\ForgeLanguage\Definitions\LanguageSwitcherDefinition;
echo component(
name: 'ForgeLanguage:language-switcher',
props: [
'definition' => new LanguageSwitcherDefinition(
showFlags: true,
showLabels: true,
showCodes: false,
),
],
);
Tune it with
LanguageSwitcherDefinition — show or
hide flags, labels, and language codes, and pass
classes for your design system.