F5 StudioF5 Studio
Skip to main content

Localization

gta6_hud ships twelve complete languages, each holding exactly 53 keys:

CodeLanguageCodeLanguage
enEnglishplPolish
deGermanesSpanish
frFrenchptPortuguese
nlDutchcsCzech
trTurkisharArabic
zhChinesethThai
config.lua
Config.Locale = 'en'

One language for the whole server — there is no per-player language picker. The setting is read on the client (navigation pill, settings menu, key-binding label, low-fuel alert) and on the server (the two stress notifications), because config.lua and locales/*.lua are both shared_scripts.

What happens when a key is missing

Lookup goes: your language → English → the literal text Translation [key] does not exist. The fallback is per key, not per file, so a half-translated file quietly mixes languages rather than breaking.

Setting Config.Locale to a code with no file in locales/ is not an error — every string simply falls back to English and the resource starts normally.

How the Files Are Built

One file per language, named after the code, with a single flat table of keys:

locales/en.lua
Locales['en'] = {

['nav_left'] = 'Turn Left',
['low_fuel'] = 'Low fuel!',
['menu_title'] = 'HUD settings',
['section_map'] = 'Map',
['option_isOutMapChecked'] = 'Show minimap outside vehicles',
-- …
}

The prefix tells you where a key is rendered, and for three of the groups the part after the prefix has to match something else in the resource:

PrefixCountWhere it is usedThe suffix must match
nav_12The turn-by-turn pill above the minimap: eight instructions plus the m, km, ft and mi unit labelsNAV_KEYS in client/core.lua
(no prefix)7Notifications: hud_restart, hud_start, cinematic_on, cinematic_off, low_fuel, stress_gain, stress_removed
menu_4menu_keymap is the label in FiveM's key-binding list; menu_title, menu_restart and menu_reset are the settings panel heading and its two buttons
section_6The section headers in the settings panel, rendered uppercase with wide letter-spacingSECTION_KEYS in client/core.lua
option_24One label per switch in the settings panelA key of Config.Menu

option_isOutMapChecked is the label for the isOutMapChecked switch — the client builds that lookup by prefixing every Config.Menu key with option_. That matters when you add a switch: a new Config.Menu key with no matching option_ entry in en.lua has nothing to fall back to, and the panel renders the literal text Translation [option_…] does not exist.

Adding Your Own Language

  1. Copy locales/en.lua to locales/<code>.lua — say locales/it.lua.
  2. Change the first line to match: Locales['it'] = {.
  3. Translate the values. Leave every key exactly as it is.
  4. Set Config.Locale = 'it' in config.lua.
  5. Restart the resource.

No manifest edit is needed — locales/*.lua is loaded as a glob, so a new file is picked up automatically.

Rules that matter

  • Keep the keys. A renamed key is a missing key, and it fails quietly: the string falls back to English and nothing is logged. If a label is stubbornly English after you translated it, a typo in the key is the first thing to check.
  • Never delete a key from en.lua. English is the floor. A key missing from your language falls back to English; a key missing from English has nothing left to fall back to, and the literal text Translation [key] does not exist is drawn in its place.
  • Never translate a value to an empty string. The lookup treats an empty value as present, so the element renders blank rather than falling back.
  • Escape apostrophes. Every value is a single-quoted Lua string, so an apostrophe inside one needs \''Recalcul de l\'itinéraire'.
  • Keep the file UTF-8 without a BOM. A BOM on the first line breaks the Lua chunk. All shipped files are UTF-8, no BOM.
  • Watch the length. This is a rendered overlay, not a document. Keep values close to the English ones: navigation instructions under ~24 characters (they wrap onto a second line in the pill above that), switch labels under ~46, section headers under ~34, notifications under ~45. Halve those numbers for Chinese and for any script whose glyphs are full-width.
  • Placeholders are safe but unused. Values pass through string.format, so %s works if you ever add one. Nothing in the shipped files uses a placeholder, and a stray % cannot break anything: the substitution is wrapped in pcall, and a failed format falls back to printing the value as written.
Check your work in game

Nothing validates translation files at startup. Set Config.Locale, restart, then open /hudmenu and set a waypoint — the settings panel and the navigation pill are where a missing key or an over-long string shows up first.

What Is Not Translatable

Some visible text in the HUD never passes through locales/.

StringWhere it comes from
Street names, the zone pill, the vehicle make and modelGame natives (GetStreetNameAtCoord, GetNameOfZone, GetLabelText). These follow the player's game language, not Config.Locale
Compass letters — N, NE, E, SE, S, SW, W, NWhtml/app.js
ALT next to the altitude readouthtml/index.html
MPH / KMH next to the speedDerived from Config.UseMPH
Money grouping — 1,250 rather than 1.250Intl.NumberFormat('en-US') in html/app.js

Weapon names are never drawn, only the icon and the ammo count, so there is nothing to translate there. See NUI & Assets before editing the interface files.

See Also

  • Configuration — where Config.Locale and Config.NavUnits live
  • HUD Menu — the switches the option_ keys label
  • NUI & Assets — editing html/index.html and html/app.js safely