Skip to main content
The Menu and Input systems provide various UI components for gathering player input, displaying menus, and showing information overlays. Includes input forms, list menus, the F1 interaction menu, confirmation dialogs, info overlays, and action text.

Overview

Access these components via COMPONENTS (client-side only).

Input Forms

Text, number, and multiline inputs

List Menus

Selectable menus with submenus

Interaction Menu

F1 menu system with custom items

Dialogs

Confirmation and info overlays
Client-Side Only: All menu components are client-side and handle NUI focus automatically.

Input Forms

The Input system displays forms for collecting user input with various field types.

Input:Show

Display an input form with multiple fields. Parameters:
NameTypeRequiredDescription
titlestringYesForm title
labelstringYesSubmit button text
inputstableYesArray of input field definitions
eventstringYesEvent to trigger on submit
datatableNoAdditional data to pass to event
Input Field Definition:
FieldTypeRequiredDescription
idstringYesUnique field identifier
typestringYesInput type: text, number, multiline
labelstringYesField label
placeholderstringNoPlaceholder text
defaultstring/numberNoDefault value
minnumberNoMin value (number type only)
maxnumberNoMax value (number type only)
requiredbooleanNoField is required
Example:
-- Client side
COMPONENTS.Input:Show(
    'Create Character',
    'Submit',
    {
        {
            id = 'first_name',
            type = 'text',
            label = 'First Name',
            placeholder = 'Enter first name',
            required = true
        },
        {
            id = 'last_name',
            type = 'text',
            label = 'Last Name',
            placeholder = 'Enter last name',
            required = true
        },
        {
            id = 'age',
            type = 'number',
            label = 'Age',
            min = 18,
            max = 100,
            default = 25,
            required = true
        },
        {
            id = 'backstory',
            type = 'multiline',
            label = 'Backstory',
            placeholder = 'Tell us about your character...',
            required = false
        }
    },
    'character:client:Create',
    { source = 'custom' }
)

-- Handle submission
AddEventHandler('character:client:Create', function(values, data)
    -- values = { first_name = "John", last_name = "Doe", age = 25, backstory = "..." }
    -- data = { source = 'custom' }

    print('First Name:', values.first_name)
    print('Last Name:', values.last_name)
    print('Age:', values.age)

    -- Send to server for processing
    TriggerServerEvent('character:server:Create', values)
end)

Input:Close

Close the input form. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Input:Close()

List Menus

The ListMenu system displays hierarchical menus with selectable items and submenus.

ListMenu:Show

Display a list menu. Parameters:
NameTypeRequiredDescription
menustableYesArray of menu item definitions
Menu Item Definition:
FieldTypeRequiredDescription
labelstringYesItem display text
descriptionstringNoItem description
iconstringNoFont Awesome icon
eventstringNoEvent to trigger on click
datatableNoData to pass to event
submenutableNoSubmenu items (same structure)
disabledbooleanNoItem is disabled
Example:
-- Client side - Vehicle menu
COMPONENTS.ListMenu:Show({
        main = {
            label = 'Vehicle Menu',
            items = {
              {
                  label = 'Lock/Unlock',
                  description = 'Toggle vehicle lock',
                  icon = "lock",
                  event = 'vehicles:client:ToggleLock',
              },
              {
                  label = 'Engine',
                  description = 'Toggle engine',
                  icon = "key",
                  event = 'vehicles:client:ToggleEngine',
              },
              {
                  label = 'Windows',
                  description = 'Roll windows up/down',
                  icon = 'window-maximize',
                  submenu = 'windows'
              },
          }
      },
      windows = {
          label = 'Roll windows up/down',
          items = {
            {
                label = 'Roll Up All',
                description = "Roll up all your windows",
                event = 'vehicles:client:WindowsUp'
            },
            {
                label = 'Roll Down All',
                description = "Roll down all your windows",
                event = 'vehicles:client:WindowsDown'
            }
        }
    },
})

-- Handle menu events
AddEventHandler('vehicles:client:ToggleLock', function(data)
    -- Toggle vehicle lock
    print('Toggling lock')
end)

AddEventHandler('vehicles:client:GiveKeys', function(data)
    -- data.plate = 'ABC123'
    print('Giving keys for:', data.plate)
end)

ListMenu:Close

Close the list menu. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.ListMenu:Close()

Interaction Menu

The Interaction system manages the F1 menu (main interaction menu) with custom menu items.

Interaction:Show

Display the interaction menu. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Interaction:Show()
Notes:
  • Usually triggered by F1 key
  • Automatically sets NUI focus
  • Shows only menu items that pass shouldShow checks

Interaction:Hide

Hide the interaction menu. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Interaction:Hide()

Interaction:RegisterMenu

Register a custom menu item in the F1 interaction menu. Parameters:
NameTypeRequiredDescription
idstringYesUnique menu identifier
labelstringYesMenu item label
iconstringYesFont Awesome icon
actionfunctionYesFunction to execute on click
shouldShowfunctionNoFunction to determine visibility
labelFuncfunctionNoDynamic label function
Example:
-- Client side - Register GPS menu
COMPONENTS.Interaction:RegisterMenu(
    'gps',
    'GPS',
    'map-location-dot',
    function()
        -- Action when clicked
        COMPONENTS.Interaction:ShowMenu({
            {
                label = 'Set Waypoint',
                icon = 'location-dot',
                event = 'gps:client:SetWaypoint'
            },
            {
                label = 'Clear Waypoint',
                icon = 'xmark',
                event = 'gps:client:ClearWaypoint'
            },
            {
                label = 'Saved Locations',
                icon = 'bookmark',
                event = 'gps:client:SavedLocations'
            }
        })
    end,
    function()
        -- Only show if player has GPS item
        return LocalPlayer.state.loggedIn
    end,
    function()
        -- Dynamic label
        local hasWaypoint = IsWaypointActive()
        if hasWaypoint then
            return 'GPS (Active)'
        else
            return 'GPS'
        end
    end
)

Interaction:ShowMenu

Display a submenu in the interaction menu. Parameters:
NameTypeRequiredDescription
itemstableYesArray of submenu items
Submenu Item Definition:
FieldTypeRequiredDescription
labelstringYesItem label
iconstringNoFont Awesome icon
eventstringNoEvent to trigger
actionfunctionNoFunction to execute
datatableNoData to pass
Example:
-- Client side
COMPONENTS.Interaction:ShowMenu({
    {
        label = 'Bank Account',
        icon = 'building-columns',
        event = 'bank:client:OpenAccount'
    },
    {
        label = 'ATM',
        icon = 'credit-card',
        event = 'bank:client:OpenATM'
    },
    {
        label = 'Transfer Money',
        icon = 'money-bill-transfer',
        action = function()
            -- Custom action
            COMPONENTS.Input:Show(
                'Transfer Money',
                'Send',
                {{ id = 'amount', type = 'number', label = 'Amount' }},
                'bank:client:Transfer'
            )
        end
    }
})

Interaction:Back

Go back to the previous menu level. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Interaction:Back()

Confirmation Dialogs

The Confirm system displays yes/no confirmation dialogs.

Confirm:Show

Display a confirmation dialog. Parameters:
NameTypeRequiredDescription
titlestringYesDialog title
eventstableYesEvents to trigger {yes, no}
descriptionstringNoDescription text
datatableNoData to pass to events
denyLabelstringNoCustom “No” button text
acceptLabelstringNoCustom “Yes” button text
Example:
-- Client side
COMPONENTS.Confirm:Show(
    'Delete Character',
    {
        yes = 'character:client:ConfirmDelete',
        no = 'character:client:CancelDelete'
    },
    'Are you sure you want to delete this character? This action cannot be undone.',
    { characterId = 123 },
    'Cancel',
    'Delete'
)

-- Handle confirmation
AddEventHandler('character:client:ConfirmDelete', function(data)
    -- data.characterId = 123
    TriggerServerEvent('character:server:Delete', data.characterId)
    COMPONENTS.Notification:Success('Character deleted')
end)

AddEventHandler('character:client:CancelDelete', function(data)
    COMPONENTS.Notification:Info('Cancelled')
end)

Confirm:Close

Close the confirmation dialog. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Confirm:Close()

Info Overlays

The InfoOverlay system displays informational overlays on screen.

InfoOverlay:Show

Display an info overlay. Parameters:
NameTypeRequiredDescription
titlestringYesOverlay title
descriptionstringYesDescription text (supports HTML)
Example:
-- Client side
COMPONENTS.InfoOverlay:Show(
    'Welcome to Los Santos',
    'Press {keybind}F1{/keybind} to open the interaction menu<br>' ..
    'Press {keybind}F2{/keybind} to open inventory<br>' ..
    'Press {keybind}F3{/keybind} to open phone'
)

-- With HTML formatting
COMPONENTS.InfoOverlay:Show(
    'Heist Rules',
    '<ul>' ..
    '<li>Stay with your team</li>' ..
    '<li>Follow the plan</li>' ..
    '<li>No civilian casualties</li>' ..
    '</ul>'
)

InfoOverlay:Close

Close the info overlay. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.InfoOverlay:Close()

InfoOverlay:IsOpen

Check if an info overlay is currently open. Returns:
TypeDescription
booleanTrue if overlay is open
Example:
-- Client side
if COMPONENTS.InfoOverlay:IsOpen() then
    print('Overlay is currently showing')
else
    print('No overlay active')
end

Action Text

The Action system displays action text on screen with keybind formatting.

Action:Show

Display action text. Parameters:
NameTypeRequiredDescription
messagestringYesAction message (supports keybind tags)
durationnumberNoDuration in ms (optional, can be persistent)
Keybind Formatting: Use {keybind}KEY{/keybind} tags to display formatted keybinds. Example:
-- Client side - Simple action text
COMPONENTS.Action:Show('Press {keybind}E{/keybind} to enter')

-- With duration (auto-hide after 5 seconds)
COMPONENTS.Action:Show('Press {keybind}E{/keybind} to interact', 5000)

-- Multiple keybinds
COMPONENTS.Action:Show(
    'Press {keybind}E{/keybind} to enter or {keybind}G{/keybind} to knock'
)

-- In a thread for proximity interaction
CreateThread(function()
    while true do
        local ped = PlayerPedId()
        local coords = GetEntityCoords(ped)
        local door = GetClosestObjectOfType(coords, 2.0, GetHashKey('prop_door'), false, false, false)

        if door ~= 0 then
            COMPONENTS.Action:Show('Press {keybind}E{/keybind} to open door')

            if IsControlJustPressed(0, 38) then -- E key
                -- Open door
                TriggerEvent('doors:client:Open', door)
            end
        else
            COMPONENTS.Action:Hide()
        end

        Wait(0)
    end
end)

Action:Hide

Hide the action text. Parameters:
NameTypeRequiredDescription
None---
Example:
-- Client side
COMPONENTS.Action:Hide()

Complete Examples

ATM System

-- Client side - ATM interaction
AddEventHandler('atm:client:Open', function()
    COMPONENTS.ListMenu:Show({
        {
            label = 'Check Balance',
            description = 'View your account balance',
            icon = 'money-bill',
            event = 'atm:client:CheckBalance'
        },
        {
            label = 'Withdraw',
            description = 'Withdraw cash',
            icon = 'hand-holding-dollar',
            action = function()
                COMPONENTS.Input:Show(
                    'Withdraw Cash',
                    'Withdraw',
                    {
                        {
                            id = 'amount',
                            type = 'number',
                            label = 'Amount',
                            min = 1,
                            max = 10000,
                            required = true
                        }
                    },
                    'atm:client:Withdraw'
                )
            end
        },
        {
            label = 'Deposit',
            description = 'Deposit cash',
            icon = 'piggy-bank',
            action = function()
                COMPONENTS.Input:Show(
                    'Deposit Cash',
                    'Deposit',
                    {
                        {
                            id = 'amount',
                            type = 'number',
                            label = 'Amount',
                            min = 1,
                            required = true
                        }
                    },
                    'atm:client:Deposit'
                )
            end
        },
        {
            label = 'Transfer',
            description = 'Transfer to another account',
            icon = 'money-bill-transfer',
            action = function()
                COMPONENTS.Input:Show(
                    'Transfer Money',
                    'Send',
                    {
                        {
                            id = 'account',
                            type = 'number',
                            label = 'Account Number',
                            required = true
                        },
                        {
                            id = 'amount',
                            type = 'number',
                            label = 'Amount',
                            min = 1,
                            required = true
                        }
                    },
                    'atm:client:Transfer'
                )
            end
        }
    })
end)

AddEventHandler('atm:client:CheckBalance', function()
    TriggerServerEvent('atm:server:GetBalance')
end)

AddEventHandler('atm:client:Withdraw', function(values)
    TriggerServerEvent('atm:server:Withdraw', values.amount)
end)

AddEventHandler('atm:client:Deposit', function(values)
    TriggerServerEvent('atm:server:Deposit', values.amount)
end)

AddEventHandler('atm:client:Transfer', function(values)
    TriggerServerEvent('atm:server:Transfer', values.account, values.amount)
end)

Vehicle Rental System

-- Client side - Vehicle rental
AddEventHandler('rental:client:OpenMenu', function()
    COMPONENTS.ListMenu:Show({
        {
            label = 'Bicycles',
            icon = 'bicycle',
            submenu = {
                {
                    label = 'BMX - $50/hour',
                    icon = 'bicycle',
                    event = 'rental:client:RentVehicle',
                    data = { model = 'bmx', price = 50 }
                },
                {
                    label = 'Cruiser - $75/hour',
                    icon = 'bicycle',
                    event = 'rental:client:RentVehicle',
                    data = { model = 'cruiser', price = 75 }
                }
            }
        },
        {
            label = 'Cars',
            icon = 'car',
            submenu = {
                {
                    label = 'Futo - $150/hour',
                    icon = 'car',
                    event = 'rental:client:RentVehicle',
                    data = { model = 'futo', price = 150 }
                },
                {
                    label = 'Blista - $200/hour',
                    icon = 'car',
                    event = 'rental:client:RentVehicle',
                    data = { model = 'blista', price = 200 }
                }
            }
        },
        {
            label = 'Return Vehicle',
            description = 'Return your rented vehicle',
            icon = 'rotate-left',
            event = 'rental:client:ReturnVehicle'
        }
    })
end)

AddEventHandler('rental:client:RentVehicle', function(data)
    COMPONENTS.Confirm:Show(
        'Rent Vehicle',
        {
            yes = 'rental:client:ConfirmRental',
            no = 'rental:client:CancelRental'
        },
        string.format('Rent %s for $%d per hour?', data.model, data.price),
        data,
        'Cancel',
        'Rent'
    )
end)

AddEventHandler('rental:client:ConfirmRental', function(data)
    TriggerServerEvent('rental:server:Rent', data.model, data.price)
    COMPONENTS.ListMenu:Close()
end)

Crafting System

-- Client side - Crafting bench
AddEventHandler('crafting:client:OpenBench', function()
    COMPONENTS.ListMenu:Show({
        {
            label = 'Weapons',
            icon = 'gun',
            submenu = {
                {
                    label = 'Pistol',
                    description = 'Requires: 5x Metal, 2x Rubber',
                    icon = 'gun',
                    event = 'crafting:client:Craft',
                    data = {
                        item = 'weapon_pistol',
                        requires = {
                            { item = 'metal', amount = 5 },
                            { item = 'rubber', amount = 2 }
                        }
                    }
                }
            }
        },
        {
            label = 'Tools',
            icon = 'wrench',
            submenu = {
                {
                    label = 'Lockpick',
                    description = 'Requires: 2x Metal',
                    icon = 'lock',
                    event = 'crafting:client:Craft',
                    data = {
                        item = 'lockpick',
                        requires = {
                            { item = 'metal', amount = 2 }
                        }
                    }
                },
                {
                    label = 'Repair Kit',
                    description = 'Requires: 3x Metal, 1x Cloth',
                    icon = 'toolbox',
                    event = 'crafting:client:Craft',
                    data = {
                        item = 'repairkit',
                        requires = {
                            { item = 'metal', amount = 3 },
                            { item = 'cloth', amount = 1 }
                        }
                    }
                }
            }
        }
    })
end)

AddEventHandler('crafting:client:Craft', function(data)
    COMPONENTS.Confirm:Show(
        'Craft Item',
        {
            yes = 'crafting:client:ConfirmCraft',
            no = 'crafting:client:CancelCraft'
        },
        'Start crafting this item?',
        data,
        'Cancel',
        'Craft'
    )
end)

AddEventHandler('crafting:client:ConfirmCraft', function(data)
    TriggerServerEvent('crafting:server:Craft', data)
    COMPONENTS.ListMenu:Close()
end)

Tutorial System

-- Client side - Tutorial overlays
AddEventHandler('tutorial:client:Start', function()
    -- Step 1: Movement
    COMPONENTS.InfoOverlay:Show(
        'Movement Controls',
        'Use {keybind}W{/keybind}{keybind}A{/keybind}{keybind}S{/keybind}{keybind}D{/keybind} to move<br>' ..
        'Hold {keybind}Shift{/keybind} to sprint<br>' ..
        'Press {keybind}Space{/keybind} to jump'
    )

    Wait(10000)
    COMPONENTS.InfoOverlay:Close()
    Wait(2000)

    -- Step 2: Interaction
    COMPONENTS.InfoOverlay:Show(
        'Interaction',
        'Press {keybind}E{/keybind} to interact with objects and NPCs<br>' ..
        'Press {keybind}F1{/keybind} to open the main menu<br>' ..
        'Press {keybind}F2{/keybind} to open your inventory'
    )

    Wait(10000)
    COMPONENTS.InfoOverlay:Close()
    Wait(2000)

    -- Step 3: Vehicles
    COMPONENTS.InfoOverlay:Show(
        'Vehicles',
        'Press {keybind}F{/keybind} to enter/exit vehicles<br>' ..
        'Hold {keybind}F{/keybind} to lock/unlock your vehicle<br>' ..
        'Press {keybind}X{/keybind} to toggle engine'
    )

    Wait(10000)
    COMPONENTS.InfoOverlay:Close()

    COMPONENTS.Notification:Success('Tutorial complete!', 5000)
end)

Admin Menu

-- Client side - Register admin menu in F1
COMPONENTS.Interaction:RegisterMenu(
    'admin',
    'Admin',
    'shield',
    function()
        COMPONENTS.Interaction:ShowMenu({
            {
                label = 'Player Management',
                icon = 'users',
                action = function()
                    COMPONENTS.Interaction:ShowMenu({
                        {
                            label = 'Teleport to Player',
                            icon = 'location-arrow',
                            action = function()
                                COMPONENTS.Input:Show(
                                    'Teleport to Player',
                                    'Teleport',
                                    {
                                        {
                                            id = 'playerId',
                                            type = 'number',
                                            label = 'Player ID',
                                            required = true
                                        }
                                    },
                                    'admin:client:TeleportToPlayer'
                                )
                            end
                        },
                        {
                            label = 'Kick Player',
                            icon = 'user-xmark',
                            action = function()
                                COMPONENTS.Input:Show(
                                    'Kick Player',
                                    'Kick',
                                    {
                                        {
                                            id = 'playerId',
                                            type = 'number',
                                            label = 'Player ID',
                                            required = true
                                        },
                                        {
                                            id = 'reason',
                                            type = 'text',
                                            label = 'Reason',
                                            required = true
                                        }
                                    },
                                    'admin:client:KickPlayer'
                                )
                            end
                        }
                    })
                end
            },
            {
                label: 'Vehicle Management',
                icon = 'car',
                action = function()
                    COMPONENTS.Interaction:ShowMenu({
                        {
                            label = 'Spawn Vehicle',
                            icon = 'plus',
                            action = function()
                                COMPONENTS.Input:Show(
                                    'Spawn Vehicle',
                                    'Spawn',
                                    {
                                        {
                                            id = 'model',
                                            type = 'text',
                                            label = 'Vehicle Model',
                                            placeholder = 'e.g., adder',
                                            required = true
                                        }
                                    },
                                    'admin:client:SpawnVehicle'
                                )
                            end
                        },
                        {
                            label = 'Delete Vehicle',
                            icon = 'trash',
                            event = 'admin:client:DeleteVehicle'
                        }
                    })
                end
            }
        })
    end,
    function()
        -- Only show if player is admin
        return LocalPlayer.state.isAdmin or false
    end
)

Best Practices

Input Validation

//GOOD - Validate on both client and server
AddEventHandler('bank:client:Withdraw', function(values)
    -- Client-side validation
    if not values.amount or values.amount <= 0 then
        COMPONENTS.Notification:Error('Invalid amount')
        return
    end

    -- Send to server for final validation
    TriggerServerEvent('bank:server:Withdraw', values.amount)
end)

// Server side
RegisterServerEvent('bank:server:Withdraw', function(amount)
    local src = source

    -- Re-validate server-side
    if type(amount) ~= 'number' or amount <= 0 then
        return -- Invalid
    end

    -- Process withdrawal
end)
//GOOD - Clear menu hierarchy
COMPONENTS.ListMenu:Show({
    {
        label = 'Main Category',
        submenu = {
            {
                label = 'Subcategory',
                submenu = {
                    {
                        label = 'Final Action',
                        event = 'some:event'
                    }
                }
            }
        }
    }
})

//BAD - Too many nested levels (confusing for users)
// Keep menu depth to 2-3 levels maximum

Cleanup

//GOOD - Close menus when done
AddEventHandler('shop:client:Purchase', function(data)
    TriggerServerEvent('shop:server:Purchase', data.item)
    COMPONENTS.ListMenu:Close() -- Close menu after action
end)

//GOOD - Close on player death/logout
AddEventHandler('playerDropped', function()
    COMPONENTS.Input:Close()
    COMPONENTS.ListMenu:Close()
    COMPONENTS.Confirm:Close()
    COMPONENTS.InfoOverlay:Close()
    COMPONENTS.Interaction:Hide()
end)

Next Steps

Keybind Formatting: In Action text and InfoOverlay descriptions, use {keybind}KEY{/keybind} tags. The system automatically converts these to styled keybind displays.
NUI Focus: Input forms, list menus, confirmation dialogs, and the interaction menu automatically handle NUI focus. Don’t manually call SetNuiFocus when using these components.