Frameworks
Adding interactions with ox_target
Use ox_target in FiveM scripts: addModel, addGlobalVehicle/Ped/Player, addLocalEntity and addEntity, box and sphere zones, option fields (label, icon, distance, groups, items, canInteract, onSelect, serverEvent), convars, removing targets and performance tips.
Overview
Targeting (the “third eye”) replaced floating “press E” prompts on most roleplay servers: players hold Alt, look at an object, ped or vehicle and pick an action from a menu. ox_target is the most widely used implementation, and adding options to it is a few lines per interaction.
Targeting models
exports.ox_target:addModel({ `prop_atm_01`, `prop_atm_02`, `prop_atm_03`, `prop_fleeca_atm` }, {
{
name = 'bank:atm',
label = 'Use ATM',
icon = 'fa-solid fa-credit-card',
distance = 1.5,
onSelect = function(data)
TriggerEvent('bank:openAtm', data.entity)
end,
},
})Global targets
exports.ox_target:addGlobalVehicle({
{
name = 'police:impound',
label = 'Impound vehicle',
icon = 'fa-solid fa-truck-pickup',
groups = { police = 0 },
distance = 2.5,
canInteract = function(entity, distance)
return GetVehicleNumberOfPassengers(entity) == 0 and IsVehicleSeatFree(entity, -1)
end,
serverEvent = 'police:impound',
},
})groups = { police = 0 } shows the option to police of grade 0 and above (ox_target reads the job from your framework). With serverEvent, the server receives a table that includes the entity’s network ID — validate it there.
Zones
local id = exports.ox_target:addBoxZone({
coords = vec3(441.2, -981.9, 30.7),
size = vec3(1.5, 1.0, 1.2),
rotation = 0,
debug = false,
options = {
{ name = 'mrpd:duty', label = 'Toggle duty', icon = 'fa-solid fa-clipboard', groups = 'police', event = 'police:toggleDuty' },
{ name = 'mrpd:armory', label = 'Armory', icon = 'fa-solid fa-gun', groups = { police = 2 }, onSelect = function() exports.ox_inventory:openInventory('shop', { type = 'PoliceArmoury' }) end },
},
})
-- exports.ox_target:removeZone(id)Option fields
| Field | Meaning |
|---|---|
name | Unique ID, used to remove the option |
label, icon, iconColor | What the player sees (Font Awesome icons) |
distance | Max distance (default 7) |
groups | Job/gang name, list, or { job = minGrade } |
items / anyItem | Required item(s) |
bones | Only when aiming at these bones (e.g. vehicle doors) |
canInteract | Function returning true/false |
onSelect / event / serverEvent / command / export | What happens on click |
Specific entities
addLocalEntity(entity, options) targets an entity that exists only on this client (a shop NPC you spawned locally). addEntity(netIds, options) targets networked entities by network ID so it works for everyone — see network IDs.
Convars and performance
setr ox_target:defaultHotkey LMENU # default key (Left Alt)
setr ox_target:leftClick 1 # select with left click
setr ox_target:toggleHotkey 0 # hold instead of toggle
setr ox_target:debug 0- Prefer
addModelor zones over global targets with heavycanInteractfunctions. - Keep
canInteractfree of callbacks and database calls — it runs repeatedly while targeting. - Remove dynamically added options when your resource stops.
Frequently asked questions
How do I add an ox_target option to a prop?
Use exports.ox_target:addModel({ model hashes }, { options }) in a client script.
How do I limit an option to a job?
Set groups = 'police' or groups = { police = 2 } for a minimum grade.
What key opens ox_target?
Left Alt by default; change it with the ox_target:defaultHotkey convar or in the player’s key bindings.
Why does my option not appear?
Check distance, groups, items and canInteract; enable debug for zones, and make sure the model hash is right.
Need this built, not just explained?
Ten years of FiveM work, from Lua to NUI
Custom resources, React NUI, ESX / QBCore / Qbox integration, OneSync performance audits and security reviews — plus the websites and SEO around your server brand.
Related guides
- FrameworksCreating zones in FiveM with ox_lib (and PolyZone)With ox_lib, create zones with lib.zones.box, lib.zones.sphere or lib.zones.poly and handle onEnter, onExit and inside. Use the restricted /zone poly|box|sphere command to draw zones in game; ox_lib saves them to created_zones.lua. PolyZone is the older library many QBCore resources still use. Zones run on the client — confirm anything important on the server.
- FrameworksGetting started with ox_libStart ox_lib before your resource, add shared_script '@ox_lib/init.lua' and lua54 'yes' to your fxmanifest, and the global lib becomes available. Use cache.ped/cache.vehicle instead of calling natives in loops, lib.callback for client↔server requests, lib.notify, lib.progressBar, lib.registerContext/lib.showContext, lib.inputDialog, lib.points and lib.zones for interaction, and lib.addCommand for commands with ACE restrictions.
- EngineeringEntity ownership, handles and network IDs in FiveMEntity handles are local to each client and to the server; never send them over events. Convert to a network ID with NetworkGetNetworkIdFromEntity, send the ID, and convert back with NetworkGetEntityFromNetworkId (or NetToVeh/NetToPed/NetToObj on the client). Each networked entity has an owner that simulates it; other clients must request control before changing it, and ownership migrates when the owner leaves.