Add a key binding players can change
Register a client command, then connect it to RegisterKeyMapping. The mapping supplies an initial key; the player can change it in FiveM’s key-binding settings. Do not hardcode a control-number polling loop for a normal menu toggle or command.
This example prints your character’s coordinates in the F8 console. It is deliberately local: displaying coordinates is not permission to teleport, award items, or change server state.
Make a complete resource
Create resources/[local]/doc_keys/fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
client_script 'client.lua'Create client.lua:
RegisterCommand('doccoords', function()
if IsPauseMenuActive() then return end
local position = GetEntityCoords(PlayerPedId())
print(('Position: %.2f, %.2f, %.2f'):format(
position.x, position.y, position.z
))
end, false)
RegisterKeyMapping('doccoords', 'Docs: print coordinates', 'keyboard', 'F7')Run refresh and ensure doc_keys in the server console. Join the server, close F8, and press F7. Open F8 again to see Position: .... You can also enter doccoords directly in F8 to test the command independently of its binding.
Press versus hold
A press action needs one command. A held action needs paired +command and -command handlers so release clears the state. Add this independent demonstration to client.lua:
local inspecting = false
RegisterCommand('+docinspect', function()
if inspecting then return end
inspecting = true
print('Inspect mode started')
end, false)
RegisterCommand('-docinspect', function()
inspecting = false
print('Inspect mode stopped')
end, false)
RegisterKeyMapping('+docinspect', 'Docs: hold inspect mode', 'keyboard', 'F6')This example changes a local flag only. If an actual feature creates cameras, disables controls, or takes NUI focus, put the corresponding cleanup in its release/close path and its resource-stop handler. Input can be interrupted; a missing key-up event must not leave a player stuck.
For a HUD that must draw every frame, a rendering loop can still be necessary. That is a different job from detecting the key. See Lua threads and timers.
Test the player’s saved binding
Open settings and locate the FiveM key-bindings section. Search for the exact label Docs: print coordinates, assign another free key, close settings, and test again. The new key should work without modifying Lua.
Changing the default key in source is not a migration of existing player preferences. Keep command names stable between releases, and tell users how to rebind an existing command rather than deleting their configuration.
| Symptom | Isolate it |
|---|---|
Typing doccoords in F8 works, but the key does not | Check the saved binding, key conflicts, and whether another UI owns focus |
| Command is unknown | Check client script loading and ensure doc_keys |
| Label is absent from settings | Confirm RegisterKeyMapping ran on the client, not the server |
| Hold action never stops | Confirm the matching -docinspect command exists and cleanup is not only in the key-down handler |
| Old key still works after updating the default | Inspect the saved user binding; do not assume source defaults overwrite it |
Keep authorization on the server
The final false in these client commands is not an access-control policy. Never protect an administrative action by hiding its key binding. When a key requests a server action, use validated network events. For server commands use restricted commands and ACE permissions.
The Cfx.re key-binding example explains the command/mapping pattern. It is an archived article; this guide does not carry forward its historical limitations as current guarantees. See also NUI focus and close behavior.