FiveM Docs
Core Resources

esx_context

esx_context reference for ESX Legacy. Open mouse-driven context menus and small forms with ESX.OpenContext, element fields, exports, keybind and pitfalls.

esx_context is the mouse-driven context menu of ESX Legacy. Use it for short action lists (an interaction menu, a boss menu) and small forms with text, number or radio inputs. You open it from client code with ESX.OpenContext, which is a wrapper around the esx_context exports.

Overview

Resourceesx_context
SideClient only
Dependencieses_extended
UIPlain HTML page (index.html), Font Awesome icons
Version1.16.x (ships with ESX Legacy 1.16.4)

The menu is a single panel. Only one context menu can be open at a time; opening a new one replaces the current one.

Configuration

config.lua contains a single global:

KeyDefaultDescription
PREVIEW_KEYBIND"LMENU" (left Alt)Default key for the previewContext key mapping, which gives mouse focus to a menu opened in preview mode. Set it to nil to skip registering the command and key mapping.

Players can rebind the key under Settings > Key Bindings > FiveM ("Preview Active Context").

Debug commands (see Commands) are only registered when Config.EnableDebug in es_extended is true.

Functions

All functions are client side and available on the ESX object once you load @es_extended/imports.lua or call exports['es_extended']:getSharedObject(). Every wrapper returns false when esx_context is not running.

ESX.OpenContext

Opens a context menu and gives it mouse and keyboard focus.

ESX.OpenContext(position, elements, onSelect, onClose, canClose)
NameTypeDescription
positionstring"left", "center" or "right" (default "right").
elementstableArray of elements.
onSelectfunction(menu, element)?Runs when the player clicks a selectable element.
onClosefunction(menu)?Runs after the menu closes, by key or by ESX.CloseContext.
canCloseboolean?false blocks closing with Escape/Backspace. Defaults to true.

The menu argument is the internal menu table: menu.eles holds the current elements (including updated inputValues), menu.position the position.

Before the elements reach the UI, ESX.OpenContext strips HTML tags from title, description, label and inputPlaceholder. Use plain text.

client/main.lua
local function openGarageMenu()
    local elements = {
        { unselectable = true, icon = 'fas fa-warehouse', title = 'Garage' },
        { icon = 'fas fa-car', title = 'Take out vehicle', name = 'take_out' },
        { icon = 'fas fa-square-parking', title = 'Park vehicle', name = 'park' },
        { disabled = true, icon = 'fas fa-wrench', title = 'Repair', description = 'Mechanics only' },
    }

    ESX.OpenContext('right', elements, function(menu, element)
        if element.name == 'take_out' then
            TriggerServerEvent('my_garage:takeOut')
        elseif element.name == 'park' then
            TriggerServerEvent('my_garage:park')
        end

        ESX.CloseContext()
    end)
end

RegisterCommand('garage', openGarageMenu, false)

ESX.PreviewContext

Shows the menu without taking mouse focus. The player keeps control of the character and can press the preview key (left Alt by default) to focus the menu and click it.

ESX.PreviewContext(position, elements, onSelect, onClose, canClose)

The parameters are the same as ESX.OpenContext. The preview key only works when an onSelect function was passed.

ESX.PreviewContext passes elements to the UI without the HTML stripping that ESX.OpenContext and ESX.RefreshContext apply.

ESX.CloseContext

Closes the open menu, releases focus and calls the onClose callback. Does nothing if no menu is open.

ESX.CloseContext()

ESX.RefreshContext

Replaces the elements and/or the position of the open menu without closing it. Callbacks and canClose stay the same.

ESX.RefreshContext(elements, position)
NameTypeDescription
elementstable?New element list. nil keeps the current elements.
positionstring?New position. nil keeps the current position.
-- Update a live counter in the open menu
local elements = {
    { unselectable = true, icon = 'fas fa-users', title = 'Players online' },
    { icon = 'fas fa-hashtag', title = tostring(#GetActivePlayers()) },
}

ESX.RefreshContext(elements)

Element fields

FieldTypeDescription
titlestringMain text of the row.
descriptionstring?Smaller text below the title.
iconstring?Font Awesome 6 free class, e.g. "fas fa-check". Use "" for no icon.
namestring?Your identifier. Use it in onSelect and to read input values.
unselectableboolean?Rendered as a header row, not clickable.
disabledboolean?Rendered grayed out, not clickable.
inputboolean?Turns the row into an input field. Input rows never trigger onSelect.
inputType"text" | "number" | "radio"Type of input.
inputPlaceholderstring?Placeholder text. For radio inputs it also acts as the preselected value when inputValue is not set.
inputValuestring | numberInitial value. Updated with what the player enters.
inputMinnumber?Lower bound for number inputs (clamped in the UI and in Lua).
inputMaxnumber?Upper bound for number inputs.
inputValuestable?Required for radio: array of { text = 'Label', value = 'key' } options.

Any other field you add (for example value or job) is kept on the element and passed back to onSelect.

Form example

Input values are written back to menu.eles when the field changes (on blur or Enter for text, on change for number and radio). Read them when the player clicks a submit row:

client/main.lua
local function openNameForm()
    local elements = {
        { unselectable = true, icon = 'fas fa-id-card', title = 'Register vehicle' },
        { icon = '', title = 'Plate text', input = true, inputType = 'text', inputPlaceholder = 'ABC 123', name = 'plate' },
        { icon = '', title = 'Seats', input = true, inputType = 'number', inputValue = 2, inputMin = 1, inputMax = 8, name = 'seats' },
        {
            icon = '', title = 'Engine', input = true, inputType = 'radio', name = 'engine', inputValue = 'petrol',
            inputValues = {
                { text = 'Petrol', value = 'petrol' },
                { text = 'Electric', value = 'electric' },
            },
        },
        { icon = 'fas fa-check', title = 'Submit', name = 'submit' },
    }

    ESX.OpenContext('center', elements, function(menu, element)
        if element.name ~= 'submit' then return end

        local values = {}
        for _, ele in ipairs(menu.eles) do
            if ele.input then
                values[ele.name] = ele.inputValue
            end
        end

        if not values.plate or values.plate == '' then
            ESX.ShowNotification('Enter a plate first', 'error')
            return
        end

        TriggerServerEvent('my_registry:register', values)
        ESX.CloseContext()
    end)
end

Validate on the server

Everything in values comes from the client. Check lengths, ranges and permissions again in your server event.

Exports

The ESX.* wrappers call these exports. You can use them directly from any client script.

ExportSignatureNotes
Openexports.esx_context:Open(position, elements, onSelect, onClose, canClose)Opens with focus. No HTML stripping when called directly.
Previewexports.esx_context:Preview(position, elements, onSelect, onClose, canClose)Opens without focus.
Closeexports.esx_context:Close()Closes and calls onClose.
Refreshexports.esx_context:Refresh(elements, position)Updates the open menu.
focusPreviewexports.esx_context:focusPreview()Gives focus to a previewed menu (same as the preview key).

State bag

While a menu is open, LocalPlayer.state['context:active'] is true. Other resources can check it to avoid opening UI on top of the menu:

if LocalPlayer.state['context:active'] then
    return
end

Controls

KeyAction
Mouse clickSelect an element
Escape / BackspaceClose the menu (ignored while typing in an input, and when canClose is false)
Left Alt (previewContext)Focus a menu opened with ESX.PreviewContext

Commands

CommandDescription
previewContextBound to PREVIEW_KEYBIND; focuses a previewed menu.
ctx:preview, ctx:open, ctx:close, ctx:formDebug commands that open sample menus. Only registered when Config.EnableDebug = true in es_extended.

Common issues

  • ESX.OpenContext returns false and nothing shows: esx_context is not started, or it starts after the resource calling it. Ensure it in server.cfg after es_extended.
  • Argument order: onSelect and onClose come before canClose, and RefreshContext takes elements first. Older snippets get both wrong.
  • Clicking an input row does nothing: by design. Add a separate submit row.
  • HTML in titles disappears: ESX.OpenContext strips tags on purpose.
  • Menu stays open after selecting: selecting does not close the menu. Call ESX.CloseContext() in onSelect when you are done.
  • Mouse cursor stuck after a script error: if your onSelect errors before closing, focus stays on the UI. Press Escape, or wrap risky code and always call ESX.CloseContext().

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page