InfraGuard

Switching Language · Localization

How to change the InfraGuard console display language — 8 locales, the admin-chosen enabled subset, and the session→cookie→profile→site-default resolution rule.

InfraGuard is an 8-language console with Korean as the head-office default and English as the global fallback. This article covers (1) how a user switches language from the header switcher, (2) how the display language is resolved on every request, and (3) how an admin chooses which languages appear in the switcher.

Overview — what it does

Every label, menu item, and message in the console goes through a translation key (__('menu.security'), etc.) rather than hardcoded English. Changing the language makes the server render the UI from that locale's translation files (resources/lang/{locale}/*.php) starting with the next request.

The supported language catalog is the 8 entries under admin in config/locales.php. Each language is always shown by its own native label, regardless of the currently active locale.

Code Native label Tag Real translation
ko 한국어 KO ✅ Fully translated (head-office default)
en English EN ✅ Fully translated (global fallback)
ja 日本語 JA ⏳ Falls back to en
zh 中文(简体) ZH ⏳ Falls back to en
es Español ES ⏳ Falls back to en
fr Français FR ⏳ Falls back to en
de Deutsch DE ⏳ Falls back to en
ru Русский RU ⏳ Falls back to en

Initially only ko and en are really translated (priority => ['ko','en'] in config/locales.php). The other six (ja·zh·es·fr·de·ru) have no translation files yet and automatically fall back to en (fallback_locale = en in config/app.php). So picking ja today still shows untranslated strings in English — the switcher lists all 8, only the wording falls back.

When to use

Layout

Header language switcher (every screen)

The header language dropdown (layouts.partials.locale-switch + ui/locale-dd.js) lists only the languages the admin has enabled. Each item shows the native label plus a short tag (e.g. KO, EN), and the current locale is marked active.

Administration ▸ Localization (managing enabled languages)

On the Administration ▸ Localization screen (reachable from the top-right button), for the 8-language catalog you can:

How to use

1) Switch from the header switcher

  1. Open the language dropdown in the header.
  2. Pick a language → the browser navigates to GET /lang/{locale}.
  3. The server stores your choice and redirects back to the previous page (redirect()->back()). The new language applies from the next render.

The switch endpoint looks like this:

GET /lang/ko      # switch to Korean
GET /lang/en      # switch to English
GET /lang/ja      # Japanese (untranslated → en fallback)

What the server (LocaleController@switch) does on switch:

Store Key Value Lifetime
Session infr_locale chosen code for the session
Session infr_lang chosen code for the session (profile-language sync)
Cookie infr_locale chosen code 1 year (persists across visits)
DB users.lang chosen code permanent (logged-in users only)

When a logged-in user switches, the choice is also persisted to users.lang (profile language), so the language survives the next login. Guest (not-logged-in) choices are kept only in session and cookie.

Calling /lang/{locale} with an unsupported (or admin-disabled) code is silently ignored and the current language is kept — no error is thrown.

2) How the display language is resolved (SetLocale)

The SetLocale middleware determines the locale on every web request (including the login screen) using the priority below. Each candidate is accepted only if it is a currently enabled language.

1. session infr_locale   (explicitly chosen via switcher this session)
2. cookie  infr_locale   (persistent choice across visits · applies to login screen before session)
3. session infr_lang     (logged-in user profile users.lang → loaded into session at login)
4. site-wide default     (Locales::primary() = first language in the enabled list)

Browser Accept-Language auto-detection is NOT performed. A first visit with no session, cookie, or profile choice is served deterministically in the admin-defined site default language, not the browser language (site-wide authority). Visitors can always change it with the header switcher.

3) Managing enabled languages (admin)

  1. Go to Administration ▸ Localization.
  2. Toggle on the languages to expose (the switcher, switching, profile language, and inventory multilingual editing all go through this set), and toggle off the rest.
  3. Reorder by drag — the top enabled language becomes the default.
  4. Save. The save is audited to infr_audit_log as localization.save.

Reducing the enabled languages immediately shrinks the header switcher's availability. As a safeguard, at least one language must stay enabled (saving zero returns 422), and if no valid code remains the system falls back to the full catalog so at least one is always guaranteed.

Data sources

Item Location
Language catalog (8 + labels) config/locales.php → admin
Real-translation priority config/locales.php → priority = ['ko','en']
Fallback locale config/app.php → fallback_locale = en
Translation files resources/lang/{locale}/{msg,menu,infra,security,...}.php (rebound via useLangPath in bootstrap/app.php)
Enabled language subset infr_setting (group=i18n, key=enabled) — CSV
Display order infr_setting (group=i18n, key=order) — CSV
Profile language users.lang
Session choice session infr_locale / infr_lang
Persistent choice cookie infr_locale (1 year)

The enabled-languages and order settings are read by App\Support\Locales with a 60-second cache. On DB error or no setting, it falls back safely to an empty array (→ full catalog). After a save, Locales::flush() invalidates the cache immediately.

-- Where the enabled set and order are stored (example)
SELECT `group`, `key`, `value` FROM infr_setting WHERE `group` = 'i18n';
-- group | key     | value
-- i18n  | order   | ko,en,ja,zh,es,fr,de,ru
-- i18n  | enabled | ko,en

Handoff to the frontend

The server passes the active locale and message pack into the view bootstrap (e.g. window.__t = @json(__('msg')), window.__locale). Vue pages and mixins use these to render client-side strings and format dates against the active UI locale.

Access

Action Minimum level
Switch language GET /lang/{locale} Guest allowed — no login required (works on the login screen too)
View/save enabled languages Administration ▸ Localization admin = 10

Troubleshooting & FAQ

The language I want is missing from the switcher

It is most likely disabled by an admin. Turn its toggle on in Administration ▸ Localization. The switcher, switching, and profile language all go through the enabled set.

I switched language but some text is still English

ja·zh·es·fr·de·ru have no real translation files yet and fall back to en (initial strategy). Seeing only the untranslated strings in English is expected. ko and en are fully translated.

First visit does not open in my browser language

That is intended. InfraGuard does not read Accept-Language; it opens in the admin-defined site default language (the first language in the enabled list). Once you switch, the choice is saved to session and cookie and kept on later visits.

After logging out and back in, my language resets

If the cookie (infr_locale, 1 year) is present, it persists. For logged-in users, the choice is also saved to users.lang and restored as the profile language on the next login. With neither cookie nor profile, it opens in the site default.

What happens with an unknown code like /lang/xx?

An unsupported code is silently ignored and the current language is kept (no error). The only valid codes are the enabled ones among the 8.

What if I disable every language?

It is blocked. Saving enforces a minimum of one (saving zero returns 422). Even if the setting became corrupt, the system falls back to the full catalog so the switcher never goes empty.

Related

Language and localization
Language and localization