Localization
gta6_hud ships twelve complete languages, each holding exactly 53 keys:
| Code | Language | Code | Language |
|---|---|---|---|
en | English | pl | Polish |
de | German | es | Spanish |
fr | French | pt | Portuguese |
nl | Dutch | cs | Czech |
tr | Turkish | ar | Arabic |
zh | Chinese | th | Thai |
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.
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'] = {
['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:
| Prefix | Count | Where it is used | The suffix must match |
|---|---|---|---|
nav_ | 12 | The turn-by-turn pill above the minimap: eight instructions plus the m, km, ft and mi unit labels | NAV_KEYS in client/core.lua |
| (no prefix) | 7 | Notifications: hud_restart, hud_start, cinematic_on, cinematic_off, low_fuel, stress_gain, stress_removed | — |
menu_ | 4 | menu_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_ | 6 | The section headers in the settings panel, rendered uppercase with wide letter-spacing | SECTION_KEYS in client/core.lua |
option_ | 24 | One label per switch in the settings panel | A 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
- Copy
locales/en.luatolocales/<code>.lua— saylocales/it.lua. - Change the first line to match:
Locales['it'] = {. - Translate the values. Leave every key exactly as it is.
- Set
Config.Locale = 'it'inconfig.lua. - 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 textTranslation [key] does not existis 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%sworks if you ever add one. Nothing in the shipped files uses a placeholder, and a stray%cannot break anything: the substitution is wrapped inpcall, and a failed format falls back to printing the value as written.
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/.
| String | Where it comes from |
|---|---|
| Street names, the zone pill, the vehicle make and model | Game natives (GetStreetNameAtCoord, GetNameOfZone, GetLabelText). These follow the player's game language, not Config.Locale |
Compass letters — N, NE, E, SE, S, SW, W, NW | html/app.js |
ALT next to the altitude readout | html/index.html |
MPH / KMH next to the speed | Derived from Config.UseMPH |
Money grouping — 1,250 rather than 1.250 | Intl.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.LocaleandConfig.NavUnitslive - HUD Menu — the switches the
option_keys label - NUI & Assets — editing
html/index.htmlandhtml/app.jssafely