FiveM Menu V1
Usage & Integration

Usage & Integration

Learn how to use FiveM Menu V1 in-game and integrate it with your custom scripts and resources.

Basic Usage

Opening the Menu

Default Keybind: Press F5 in-game to open the menu (configurable in config/controls.json)

Alternative Methods:

Via client-side event:

TriggerEvent('fivem-menu:openMenu')

Via command:

RegisterCommand('menu', function()
    TriggerEvent('fivem-menu:openMenu')
end)

Navigating the Menu

ActionDefault KeyAlternative
Navigate Up↑ Arrow UpW
Navigate Down↓ Arrow DownS
Navigate Left← Arrow LeftA
Navigate Right→ Arrow RightD
Select ItemEnter-
Go BackBackspace-
Close MenuESC-

Menu Structure

Menus can have multiple levels:

  • Main Categories: Top-level menu items
  • Submenus: Categories can contain nested items
  • Actions: Final items that execute functions

Integration with Scripts

Opening Menu from Other Resources

From Client Script:

-- Simple open
TriggerEvent('fivem-menu:openMenu')
 
-- Open with callback
TriggerEvent('fivem-menu:openMenu', function(closed)
    if closed then
        print('Menu was closed')
    end
end)

From Server Script:

-- Open menu for specific player
TriggerClientEvent('fivem-menu:openMenu', playerId)
 
-- Open menu for all players
TriggerClientEvent('fivem-menu:openMenu', -1)

Closing Menu Programmatically

-- Close the menu
TriggerEvent('fivem-menu:closeMenu')
 
-- Close with callback
TriggerEvent('fivem-menu:closeMenu', function()
    print('Menu closed successfully')
end)

Custom Menu Actions

Registering Custom Actions

Client-side Action:

-- Register action handler
RegisterNetEvent('fivem-menu:action:customAction', function(data)
    local playerPed = PlayerPedId()
    
    -- Your custom logic
    SetEntityHealth(playerPed, 200)
    
    -- Show notification
    TriggerEvent('fivem-menu:notify', 'Custom action executed!', 'success')
end)

Server-side Action:

-- Register server action
RegisterNetEvent('fivem-menu:serverAction:giveItem', function(itemName, amount)
    local source = source
    local xPlayer = ESX.GetPlayerFromId(source) -- or QBCore
    
    if xPlayer then
        xPlayer.addInventoryItem(itemName, amount)
        TriggerClientEvent('fivem-menu:notify', source, 'Item received!', 'success')
    end
end)

Add to menu-items.json:

{
  "label": "Custom Action",
  "icon": "star",
  "action": "customAction",
  "description": "Execute custom function"
}

Action with Parameters

Menu item with parameters:

{
  "label": "Get Money",
  "icon": "dollar-sign",
  "action": "giveMoney",
  "actionParams": {
    "amount": 1000,
    "account": "bank"
  }
}

Handler with parameters:

RegisterNetEvent('fivem-menu:action:giveMoney', function(params)
    local source = source
    local amount = params.amount or 0
    local account = params.account or 'cash'
    
    -- ESX example
    local xPlayer = ESX.GetPlayerFromId(source)
    if xPlayer then
        xPlayer.addAccountMoney(account, amount)
    end
    
    -- QBCore example
    -- local Player = QBCore.Functions.GetPlayer(source)
    -- Player.Functions.AddMoney(account, amount)
end)

Framework Integration Examples

ESX Integration

Get Player Data:

RegisterNetEvent('fivem-menu:action:showJob', function()
    ESX.TriggerServerCallback('esx:getPlayerData', function(data)
        local job = data.job
        TriggerEvent('fivem-menu:notify', 
            string.format('Job: %s - Grade: %s', job.label, job.grade_label), 
            'info'
        )
    end)
end)

Check Player Job:

-- Add this to menu-items.json with requiredJob
{
  "label": "Police Actions",
  "icon": "shield",
  "requiredJob": "police",
  "submenu": [...]
}

Job-restricted action:

RegisterNetEvent('fivem-menu:action:policeAction', function()
    ESX.TriggerServerCallback('esx:getPlayerData', function(data)
        if data.job.name == 'police' then
            -- Execute police-specific action
            TriggerEvent('fivem-menu:notify', 'Police action executed', 'success')
        else
            TriggerEvent('fivem-menu:notify', 'You must be police!', 'error')
        end
    end)
end)

QBCore Integration

Get Player Data:

RegisterNetEvent('fivem-menu:action:checkMoney', function()
    local PlayerData = QBCore.Functions.GetPlayerData()
    local cash = PlayerData.money['cash']
    local bank = PlayerData.money['bank']
    
    TriggerEvent('fivem-menu:notify', 
        string.format('Cash: $%s | Bank: $%s', cash, bank), 
        'info'
    )
end)

Job-based menu items:

-- Server-side permission check
QBCore.Functions.CreateCallback('fivem-menu:hasJob', function(source, cb, jobName)
    local Player = QBCore.Functions.GetPlayer(source)
    if Player.PlayerData.job.name == jobName then
        cb(true)
    else
        cb(false)
    end
end)

Event System

Available Events

Client Events:

-- Menu opened
AddEventHandler('fivem-menu:onOpen', function()
    print('Menu opened')
end)
 
-- Menu closed
AddEventHandler('fivem-menu:onClose', function()
    print('Menu closed')
end)
 
-- Action executed
AddEventHandler('fivem-menu:onAction', function(actionName, params)
    print('Action:', actionName)
end)
 
-- Show notification
TriggerEvent('fivem-menu:notify', 'Message', 'success') -- success, error, info, warning

Server Events:

-- Player opened menu
RegisterNetEvent('fivem-menu:playerOpened', function()
    local source = source
    print('Player ' .. source .. ' opened menu')
end)
 
-- Log action execution
RegisterNetEvent('fivem-menu:logAction', function(actionName)
    local source = source
    print('Player ' .. source .. ' executed: ' .. actionName)
end)

Permission System

Checking Permissions

Client-side check:

RegisterNetEvent('fivem-menu:action:adminTeleport', function()
    TriggerServerCallback('fivem-menu:hasPermission', function(hasPermission)
        if hasPermission then
            -- Execute admin action
            local waypoint = GetFirstBlipInfoId(8)
            if DoesBlipExist(waypoint) then
                local coords = GetBlipCoords(waypoint)
                SetEntityCoords(PlayerPedId(), coords.x, coords.y, coords.z)
                TriggerEvent('fivem-menu:notify', 'Teleported to waypoint', 'success')
            end
        else
            TriggerEvent('fivem-menu:notify', 'No permission', 'error')
        end
    end, 'admin.teleport')
end)

Server-side permission check:

-- ESX Permission Check
ESX.RegisterServerCallback('fivem-menu:hasPermission', function(source, cb, permission)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    if xPlayer.getGroup() == 'admin' or xPlayer.getGroup() == 'superadmin' then
        cb(true)
    else
        cb(false)
    end
end)
 
-- QBCore Permission Check
QBCore.Functions.CreateCallback('fivem-menu:hasPermission', function(source, cb, permission)
    local Player = QBCore.Functions.GetPlayer(source)
    
    if QBCore.Functions.HasPermission(source, permission) then
        cb(true)
    else
        cb(false)
    end
end)

Practical Examples

Example 1: Vehicle Spawn Menu

Add to menu-items.json:

{
  "label": "Spawn Vehicle",
  "icon": "car",
  "submenu": [
    {
      "label": "Adder",
      "action": "spawnVehicle",
      "actionParams": {"model": "adder"}
    },
    {
      "label": "T20",
      "action": "spawnVehicle",
      "actionParams": {"model": "t20"}
    }
  ]
}

Handler:

RegisterNetEvent('fivem-menu:action:spawnVehicle', function(params)
    local model = params.model
    local playerPed = PlayerPedId()
    local coords = GetEntityCoords(playerPed)
    local heading = GetEntityHeading(playerPed)
    
    RequestModel(model)
    while not HasModelLoaded(model) do
        Wait(100)
    end
    
    local vehicle = CreateVehicle(model, coords.x + 2, coords.y, coords.z, heading, true, false)
    TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
    
    TriggerEvent('fivem-menu:notify', 'Vehicle spawned!', 'success')
end)

Example 2: Player Management (Admin)

Menu configuration:

{
  "label": "Player Management",
  "icon": "users",
  "requiredPermission": "admin",
  "submenu": [
    {
      "label": "Heal All Players",
      "icon": "heart",
      "action": "healAllPlayers"
    },
    {
      "label": "Teleport All to Me",
      "icon": "map-pin",
      "action": "teleportAllToMe",
      "confirmDialog": true
    }
  ]
}

Server-side handler:

RegisterNetEvent('fivem-menu:serverAction:healAllPlayers', function()
    local source = source
    
    -- Check admin permission
    if IsPlayerAdmin(source) then
        local players = GetPlayers()
        for _, playerId in ipairs(players) do
            TriggerClientEvent('fivem-menu:heal', playerId)
        end
        
        TriggerClientEvent('fivem-menu:notify', source, 'All players healed!', 'success')
    end
end)

Example 3: Garage Integration

Combine with garage system:

RegisterNetEvent('fivem-menu:action:openGarage', function()
    -- Check if player is near garage
    local playerCoords = GetEntityCoords(PlayerPedId())
    local garageCoords = vector3(213.32, -809.09, 31.01)
    local distance = #(playerCoords - garageCoords)
    
    if distance < 10.0 then
        TriggerEvent('esx_garage:openGarage') -- or your garage system event
        TriggerEvent('fivem-menu:closeMenu')
    else
        TriggerEvent('fivem-menu:notify', 'You are not near a garage', 'error')
    end
end)

Tips & Best Practices

Performance

  1. Use server callbacks for permission checks
  2. Cache frequently accessed data
  3. Avoid heavy operations in menu actions
  4. Use lazy loading for submenus with many items

User Experience

  1. Provide clear action descriptions
  2. Use confirmation dialogs for destructive actions
  3. Show notifications after action completion
  4. Keep menu structure simple and intuitive

Security

  1. Always validate permissions server-side
  2. Never trust client-side permission checks
  3. Log sensitive actions
  4. Implement rate limiting for critical actions

Debugging

  1. Enable debug mode in config/debug.json
  2. Check F8 console for errors
  3. Use server console for server-side issues
  4. Test actions on development server first

Next Steps