API REFERENCE#
Use these client-side exports to dynamically add items, create nested menus, remove items, or control the radial menu from any resource.
QUICK START#
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')
ITEM STRUCTURE#
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. |
Trigger Options#
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.
canAccess#
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.
EXPORT REFERENCE#
onexRadialItemAdd#
exports['onex-radialmenu']:onexRadialItemAdd(item, id, parent_id)
Adds a menu item to the radial menu. Returns the assigned menuID.
Parameters:
- item (table) — Item configuration (see Item Structure)
- id (string | number, optional) — Unique identifier for this item
- parent_id (string | number, optional) — If provided, appends this item to the
subMenuof an existing parent
Examples:
- Basic root item:
exports['onex-radialmenu']:onexRadialItemAdd({ label = 'Toggle Engine', closeRadialMenu = true, icon = { address = 'fa-solid fa-power-off' }, trigger = { command = 'engine' } }, 'engine_toggle')
- Nested menu with children:
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')
- Add a child to an existing parent:
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.
onexRemoveRadialItem#
exports['onex-radialmenu']:onexRemoveRadialItem(parent_id, child_id)
Parameters:
- parent_id (string | number) — ID of the item to remove, or the parent containing the child
- child_id (string | number, optional) — If provided, removes only this child from the parent's submenu
-- 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')
clearRadialItems#
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.
disableRadial#
exports['onex-radialmenu']:disableRadial(toggle)
Parameters:
- toggle (boolean | nil):
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()
closeRadialMenu#
exports['onex-radialmenu']:closeRadialMenu()
Programmatically closes the radial menu from any script.
AddEventHandler('onEnterRestrictedZone', function() exports['onex-radialmenu']:closeRadialMenu() end)
ConvertToOnexRadial#
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 })
COMPATIBILITY EXPORTS#
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.
QBX Wrappers#
-- Add item(auto-converts from simplified format) exports['onex-radialmenu']:addRadialItem(data, parent_id) -- Remove item exports['onex-radialmenu']:removeRadialItem(parent_id, child_id)
QB Wrappers#
-- 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.
BEHAVIORS & LIMITS#
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).
TROUBLESHOOTING#
- Nothing shows up — Confirm IDs are unique and the item has
label,icon, andtrigger. - Events don't fire — Check
event.nameandevent.type('client'or'server'), and verify the event handler exists. - Icons don't render — Use the full FontAwesome class (e.g.,
'fa-solid fa-car') or a valid image URL. - Menu won't open — Verify the keybind (default
F1) and thatdisableRadial(false)is set. - Item not visible — Check if
canAccessreturnstrue. Errors incanAccesswill hide the item silently (check server console for logged errors). - Exceeded 6 items — Root items beyond 6 are grouped into an automatic overflow menu.