Quick Start
Practical examples covering the most common LastMenu use cases.
1 min read
The base pattern
Every LastMenu component follows the same pattern: export → builder → methods.
local UI = exports['LastMenu']
UI:<type>(function(builder)
builder:<method>(...)
end) No require, no framework. Just an export.
Example 1 — Simple garage menu
A context menu with action buttons, a price badge, and a hold-to-confirm action.
local UI = exports['LastMenu']
RegisterCommand('garage', function()
UI:context(function(menu)
menu:title("Garage")
menu:description("Vehicle maintenance and modifications")
menu:header("Repairs")
menu:button("Repair engine", {
icon = "wrench",
badge = "$500",
confirm_hold = true, -- hold 1.5s to confirm
cb = function() TriggerServerEvent('garage:repair', 'engine') end,
})
menu:button("Repair bodywork", {
icon = "car",
badge = "$200",
cb = function() TriggerServerEvent('garage:repair', 'body') end,
})
menu:header("Statistics")
menu:stat("Engine", {
value = function() return GetVehicleEngineHealth(GetVehiclePedIsIn(PlayerPedId(), false)) / 10 end,
max = 100,
icon = "activity",
suffix = "%",
refresh = 1000,
})
end)
end, false) Example 2 — Bank transfer form
A blocking multi-field form with NUI-side validation.
RegisterCommand('transfer', function()
Citizen.CreateThread(function()
local values = exports.LastMenu:input_async(function(b)
b:title("Bank Transfer")
b:field("Recipient", {
type = "text",
placeholder = "Player name",
maxlen = 30,
})
b:field("Amount", {
type = "number",
min = 1,
max = 100000,
})
b:field("Reason", {
type = "text",
maxlen = 50,
})
end)
if not values then return end -- cancelled by player
TriggerServerEvent('bank:transfer', values[1], values[2], values[3])
exports.LastMenu:notify(function(n)
n:message("Transferred $" .. values[2] .. " to " .. values[1])
n:type("success")
end)
end)
end, false) Example 3 — Quick radial menu
A radial menu accessible at any time, with a vehicle sub-menu.
local UI = exports['LastMenu']
local quickMenu = UI:radial_build(function(r)
r:center_label("Quick actions")
r:button("Heal", {
icon = "heart",
cb = function() TriggerServerEvent('player:heal') end,
})
r:button("Vehicle", {
icon = "car",
submenu = function(sub)
sub:center_label("Vehicle")
sub:button("Repair", { icon = "wrench", cb = function() TriggerServerEvent('vehicle:repair') end })
sub:button("Flip", { icon = "rotate-ccw", cb = function() TriggerServerEvent('vehicle:flip') end })
sub:button("Clean", { icon = "droplets", cb = function() TriggerServerEvent('vehicle:clean') end })
end,
})
r:button("Missions", {
icon = "zap",
visible = function() return exports['myresource']:hasMissions() end,
cb = function() exports['myresource']:openMissions() end,
})
end)
RegisterCommand('wheel', function() quickMenu.open() end, false) Example 4 — Progress bar with animation
Crafting with ped animation, attached prop, and server-side progress.
local function startCrafting()
exports.LastMenu:progress(function(p)
p:label("Crafting in progress...")
p:icon("hammer")
p:duration(8000)
p:cancel(true)
p:anim({
dict = "amb@world_human_welding@male@base",
clip = "base",
flag = 1,
})
p:prop({
model = "prop_tool_torch",
bone = 57005,
offset = vector3(0.12, 0.03, 0.0),
rot = vector3(0.0, 0.0, 0.0),
})
p:onComplete(function()
TriggerServerEvent('crafting:complete')
exports.LastMenu:notify(function(n)
n:message("Crafting complete!")
n:type("success")
end)
end)
p:onCancel(function()
exports.LastMenu:notify(function(n)
n:message("Crafting cancelled.")
n:type("warning")
end)
end)
end)
end Example 5 — Interactive zone with target
A shop triggered by proximity, with a conditional action (weapon drawn).
local UI = exports['LastMenu']
local shopId = UI:target_add_sphere(vector3(25.0, -1343.0, 29.5), 2.0, {
label = "24/7",
icon = "store",
on_enter = function()
UI:notify(function(n) n:message("Press E to interact") n:type("info") end)
end,
actions = {
{
label = "Shop",
icon = "shopping-cart",
cb = function()
UI:context(function(menu)
menu:title("24/7 — Store")
menu:button("Water — $2", { icon = "droplets", badge = "$2", cb = function() end })
menu:button("Chips — $5", { icon = "package", badge = "$5", cb = function() end })
end)
end,
},
{
label = "Rob",
icon = "alert-triangle",
condition = function() return IsPedArmed(PlayerPedId(), 6) end,
cb = function() TriggerServerEvent('robbery:start') end,
},
},
})
-- Always clean up on resource stop
AddEventHandler('onResourceStop', function(res)
if res == GetCurrentResourceName() then
UI:target_remove(shopId)
end
end) Next steps
- Explore all options of the Context Menu
- Learn how the reactivity engine works
- Customize the appearance with CSS Theming