Commands#
Radial Menu registers its commands on the client, so any player can type them. Only the editor is guarded: the server decides who may open /radialedit and checks again on every save. The rest exist to open things, or to get a player out of trouble.
Command | Who | Description |
|---|---|---|
| Everyone | Opens the wheel, or closes it if it is open. The name is |
| Everyone | Opens or closes the player's settings. The name is |
| Admins | Opens or closes the editor. For anybody else nothing happens. The name cannot be changed. |
| Everyone | Rebuilds the menu from the player's current job and gang and from what other resources added. For a wheel that looks out of date. |
| Everyone | Closes the wheel and gives the mouse back to the game. Also on |
| Everyone | Reloads the whole interface and releases the mouse — the bigger hammer when |
| Everyone | Fetches the editor's menu from the server again and prints in F8 whether the override is active, followed by its contents. |
| Everyone | Prints whether the wheel is open and who holds the mouse. Only prints with |
Key bindings#
Each player can change these under Settings → Key Bindings → FiveM, and FiveM remembers their choice:
Binding | Default | Does |
|---|---|---|
Radial Menu: Open |
| Opens the wheel. |
Radial Menu: Reset NUI Focus (emergency) |
| Same as |
Radial Menu: Dump state (debug) |
| Same as |
Events#
For opening the wheel from your own scripts — a phone app, a keybind of your own, a tutorial — and for reacting when it opens or closes:
-- Client side
TriggerEvent('qs-radialmenu:client:openMenu')
TriggerEvent('qs-radialmenu:client:closeMenu')
-- Server side, for one player
TriggerClientEvent('qs-radialmenu:client:openMenu', source)
-- Fired by the wheel itself
AddEventHandler('qs-radialmenu:client:onRadialmenuOpen', function()
-- e.g. hide your HUD
end)
AddEventHandler('qs-radialmenu:client:onRadialmenuClose', function()
-- and bring it back
end)Vehicle events#
The Vehicle section is built from these client events. Use them on your own buttons — as a client action in the editor, or with TriggerEvent:
Event | Does |
|---|---|
| Opens or shuts one door: 0 driver, 1 passenger, 2 rear left, 3 rear right, 4 hood, 5 trunk. |
| Shuts every door when half or more are open, and opens them otherwise. |
| Rolls one window down or up, in the same order as the doors. |
| Every window, the same way. |
| Moves into that seat if it is free and the vehicle is below 100 km/h. |
| Turns a vehicle extra on or off. |
| Engine on or off, from the driver's seat. |
| Puts the vehicle the player is in back on its wheels. |
Doors and windows act on the vehicle the player is in or facing; seats, extras, the engine and the flip need the player inside it.
Client Exports#
Every export is client side. They are how another resource adds its own section to the wheel — a shop, a job, a rental that offers a Return button only while something is rented — and how it adds entries to the editor's library.
Opening and closing the wheel
exports['qs-radialmenu']:OpenMenu()
exports['qs-radialmenu']:CloseMenu()CreateCategory
Adds a section at the top level of the wheel, or inside another section by its ID.
local ok, err = exports['qs-radialmenu']:CreateCategory('mystore', {
label = 'My Store',
icon = 'Store',
})
-- Nested inside another section
exports['qs-radialmenu']:CreateCategory('mystore_admin', {
label = 'Manage',
icon = 'Shield',
parent = 'mystore',
job = { shopowner = { grade = 2 } },
})Field | Required | Description |
|---|---|---|
| Yes | The text and a Lucide icon name. |
| No | A section created with this export, or one in config/menu.lua that has an |
| No | The same formats as in config/menu.lua. |
| No | A visibility function. Only works when called from inside Radial Menu's own files. |
Returns true, or false and a message. IDs are global across every resource, so prefix them with your resource's name. A section with no visible buttons is not shown.
CreateItem
Adds a button to a section created with CreateCategory, and returns its ID so you can remove it later.
-- A client event
local itemId, err = exports['qs-radialmenu']:CreateItem('mystore', {
label = 'Open shop', icon = 'ShoppingCart',
event = 'mystore:client:open', eventType = 'client',
})
-- A server event, for one job
exports['qs-radialmenu']:CreateItem('mystore_admin', {
label = 'Restock', icon = 'PackagePlus',
event = 'mystore:server:restock', eventType = 'server',
job = 'shopowner',
})
-- A command, keeping the wheel open
exports['qs-radialmenu']:CreateItem('mystore', {
label = 'Wave', icon = 'Hand',
event = 'e wave', eventType = 'command',
closesRadial = false,
})Field | Required | Description |
|---|---|---|
| Yes | The text and a Lucide icon name. |
| One of the two | The event or command to run. Works from any resource. The event receives the table you passed. |
| One of the two | A function. Only works when called from inside Radial Menu's own files. |
| No |
|
| No |
|
| No | As for |
Returns the new item's ID, or nil and a message. If the wheel is open, the player sees the new button at once.
RemoveCategory and RemoveItem
exports['qs-radialmenu']:RemoveItem('mystore', itemId) -- one button
exports['qs-radialmenu']:RemoveCategory('mystore') -- the section and everything in itBoth return true, or false if there was nothing to remove, so calling them twice is harmless. You rarely need them: when a resource stops or restarts, everything it created is removed automatically.
Attaching to a section of config/menu.lua
Give the section an id, then create your own section inside it and put your buttons there:
-- config/menu.lua
{
id = 'services',
label = 'Services',
icon = 'Briefcase',
type = 'category',
items = { ... },
},
-- your resource
exports['qs-radialmenu']:CreateCategory('mechanic_shop', {
label = 'Mechanic', icon = 'Wrench',
parent = 'services',
})
exports['qs-radialmenu']:CreateItem('mechanic_shop', {
label = 'Call a tow', icon = 'Truck',
event = 'mechanic:client:callTow',
})Sections are found by ID only, never by label. CreateItem only accepts sections created with CreateCategory, which is why the buttons go into a section of your own.
RegisterAction and RegisterPredicate
Add entries to the library the editor's dropdowns are built from. They appear in /radialedit straight away, and disappear when the resource that added them stops.
exports['qs-radialmenu']:RegisterAction({
id = 'mystore.open',
label = 'Open my store',
type = 'client', -- client | server | command | qbcommand
event = 'mystore:client:open',
})
exports['qs-radialmenu']:UnregisterAction('mystore.open')
local actions = exports['qs-radialmenu']:ListActions() -- { id, label, type, event, hasFn }
local conditions = exports['qs-radialmenu']:ListPredicates() -- { id, label }RegisterAction also accepts an fn function instead of type and event, and RegisterPredicate (id, label, fn) always takes one. Functions only work from inside Radial Menu's own files, so register those in custom/registry.lua — see Integrations. UnregisterPredicate(id) removes a condition.
A complete example
A rental script that offers Return vehicle only while something is rented:
-- client/main.lua of your resource — ensure it after qs-radialmenu
CreateThread(function()
exports['qs-radialmenu']:CreateCategory('myrental', {
label = 'Rentals', icon = 'KeyRound',
})
exports['qs-radialmenu']:CreateItem('myrental', {
label = 'Rent a car', icon = 'Car',
event = 'myrental:client:open',
})
end)
local returnItem
RegisterNetEvent('myrental:client:rented', function()
returnItem = exports['qs-radialmenu']:CreateItem('myrental', {
label = 'Return vehicle', icon = 'Undo2',
event = 'myrental:client:return',
})
end)
RegisterNetEvent('myrental:client:return', function()
if returnItem then
exports['qs-radialmenu']:RemoveItem('myrental', returnItem)
returnItem = nil
end
-- ...return the car
end)
-- No cleanup on stop: the section is removed with the resource.Legacy exports
Kept so older integrations keep working. New code should use the exports above.
Export | Behaviour |
|---|---|
| Same as |
| Same as |
| The qb-radialmenu style: |
| Each time the wheel opens, calls that resource's |
What other resources add lives in memory. If Radial Menu itself is restarted, those sections are gone until each resource runs its code again — restart them after it, or keep them ensured after
qs-radialmenuso a full server restart always loads them in order.
Server Side#
There are no server exports: the wheel is built on each player's own game. To open it for a player from the server, trigger the client event shown above with their server id.
About the Errors#
The exports never throw. When something is wrong they return false or nil with a short message — parent not found: services, category already exists: mystore — so print the second return value while developing. Every message and what it means is listed in Common Errors.



