Use these client-side exports to dynamically add items, create nested menus, remove items, or control the radial menu from any resource.
Add a simple item and test it:
exports['onex-radialmenu']:onexRadialItemAdd({ label = 'Hello World', closeRadialMenu = true, icon = { address = 'fa-solid fa-hand' }, trigger = { onSelect = function() print('Hello from radial!') end } }, 'hello_world')
Open the radial menu (default F1) and select the item. Remove it with:
exports['onex-radialmenu']:onexRemoveRadialItem('hello_world')
Every menu item follows this structure. Root items and sub-items share the same fields with minor differences noted below.
{ -- Required label = 'Display Text', icon = { address = 'fa-solid fa-star' }, trigger = {}, -- Optional closeRadialMenu = false, closeSubMenu = false, canAccess = function() return true end, subMenu = { ... }, id = 'unique_id', }
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Text shown in the menu. title is accepted as a fallback. |
icon | table | Yes | { address = 'fa-solid fa-icon' } — FontAwesome class or image URL. |
trigger | table | Yes | Action to perform on click. Use {} for submenu-only parents. |
closeRadialMenu | boolean | No | Close the entire radial menu after clicking. Default false. |
closeSubMenu | boolean | No | Close the submenu panel after clicking. Used in sub-items. Default false. |
canAccess | function | No | Return true to show, false to hide. Evaluated every time the menu opens. |
subMenu | table | No | Array of child items (max 2 levels deep). |
id | string | number | No | Unique identifier. Required for removal or when used as a submenu child. |
Each trigger table supports one or more of the following:
trigger = { -- Direct callback onSelect = function() print('Clicked!') end, -- FiveM event event = { name = 'my:event', type = 'client', -- 'client' or 'server' args = { key = 'value' } -- passed to the event handler }, -- Chat command command = 'myCommand' }
All three trigger types can coexist on the same item. Each one that is present will execute when the item is selected.
Use canAccess to conditionally show or hide items based on game state:
exports['onex-radialmenu']:onexRadialItemAdd({ label = 'Engine On/Off', icon = { address = 'fa-solid fa-power-off' }, closeRadialMenu = true, canAccess = function() return IsPedInAnyVehicle(PlayerPedId(), false) end, trigger = { onSelect = function() -- toggle engine end } }, 'engine_toggle')
canAccess is evaluated each time the radial menu opens, not at registration time. Errors are caught with pcall and logged — a failing canAccess hides the item.
exports['onex-radialmenu']:onexRadialItemAdd(item, id, parent_id)
Adds a menu item to the radial menu. Returns the assigned menuID.
Parameters:
subMenu of an existing parentExamples:
exports['onex-radialmenu']:onexRadialItemAdd({ label = 'Toggle Engine', closeRadialMenu = true, icon = { address = 'fa-solid fa-power-off' }, trigger = { command = 'engine' } }, 'engine_toggle')
exports['onex-radialmenu']:onexRadialItemAdd({ label = 'Vehicle Options', closeRadialMenu = false, icon = { address = 'fa-solid fa-car' }, trigger = {}, subMenu = { { id = 'engine_toggle', label = 'Toggle Engine', closeSubMenu = true, closeRadialMenu = true, icon = { address = 'fa-solid fa-power-off' }, trigger = { event = { name = 'vehicle:toggleEngine', type = 'client' }, onSelect = function() print('Engine toggled!') end } } } }, 'vehicle_menu')
exports['onex-radialmenu']:onexRadialItemAdd({ id = 'lock_doors', label = 'Lock Doors', closeSubMenu = true, closeRadialMenu = true, icon = { address = 'fa-solid fa-lock' }, trigger = { onSelect = function() print('Doors locked!') end } }, 'lock_doors', 'vehicle_menu') -- parent_id = 'vehicle_menu'
When using numeric IDs, keep them sequential (1, 2, 3, ...). Reusing an existing ID overwrites that item.
exports['onex-radialmenu']:onexRemoveRadialItem(parent_id, child_id)
Parameters:
-- Remove a specific submenu child exports['onex-radialmenu']:onexRemoveRadialItem('vehicle_menu', 'engine_toggle') -- Remove an entire root item and all its children exports['onex-radialmenu']:onexRemoveRadialItem('vehicle_menu')
exports['onex-radialmenu']:clearRadialItems()
Removes all items from the radial menu, including static config items and all stored function references.
This is a full reset — config items (Config.menuItems) are also cleared. Use with caution.
exports['onex-radialmenu']:disableRadial(toggle)
Parameters:
true — disable the radial menufalse — enable the radial menunil (or omitted) — toggle the current state-- Disable during a cutscene exports['onex-radialmenu']:disableRadial(true) -- Re-enable after exports['onex-radialmenu']:disableRadial(false) -- Toggle current state exports['onex-radialmenu']:disableRadial()
exports['onex-radialmenu']:closeRadialMenu()
Programmatically closes the radial menu from any script.
AddEventHandler('onEnterRestrictedZone', function() exports['onex-radialmenu']:closeRadialMenu() end)
exports['onex-radialmenu']:ConvertToOnexRadial(data)
Converts an OxLib/QBX-style item into the native onex format. Accepts a single item table or an array of items.
Simplified input format:
{ id = 'myItem', label = 'My Item', -- or title icon = 'star', -- icon name only — 'fa-solid fa-' is prepended event = 'my:event', -- flat event name type = 'client', -- 'client' or 'server' args = { key = 'value' }, -- event arguments onSelect = function() end, -- direct callback shouldClose = true, -- maps to closeRadialMenu canAccess = function() return true end, items = { ... }, -- sub-items(converted to subMenu) job = { name = 'police', grade = 2 } }
local nativeItem = exports['onex-radialmenu']:ConvertToOnexRadial({ id = 'patrol', label = 'Go on Patrol', icon = 'car-side', event = 'police:startPatrol', type = 'client', shouldClose = true })
onex-radialmenu provides qbx_radialmenu and qb-radialmenu via the provide directive. Existing scripts that call exports['qb-radialmenu'] or exports['qbx_radialmenu'] will automatically route to onex-radialmenu — no code changes needed.
-- Add item(auto-converts from simplified format) exports['onex-radialmenu']:addRadialItem(data, parent_id) -- Remove item exports['onex-radialmenu']:removeRadialItem(parent_id, child_id)
-- Add item(auto-converts from simplified format) exports['onex-radialmenu']:AddOption(data, id, parent_id) -- Remove item exports['onex-radialmenu']:RemoveOption(parent_id, child_id)
These wrappers accept the simplified format (see ConvertToOnexRadial) and internally convert before adding.
6 Root Slots — The radial menu supports up to 6 root-level items. When more items are present, the UI automatically creates a "More" overflow entry on the 6th slot.
Auto-Cleanup — When a resource that added items via exports stops or restarts, all its dynamically added items are automatically removed. No manual cleanup needed.
Static vs Dynamic — Items in Config.menuItems are static (loaded once at startup). Items added via exports are dynamic (merged each time the menu opens).
Submenu Depth — Submenus support up to 2 levels of nesting (root → submenu → nested submenu).
label, icon, and trigger.event.name and event.type ('client' or 'server'), and verify the event handler exists.'fa-solid fa-car') or a valid image URL.F1) and that disableRadial(false) is set.canAccess returns true. Errors in canAccess will hide the item silently (check server console for logged errors).Last updated 2 months ago