Exports
Every export with its signature, its parameters and a real example in context. Client, server and events.
None of them break when optional fields are missing, and none return anything
except isTextUIOpen. Call them from wherever you like without wrapping them in
checks.
Client
show(data) → id
Fires a notification. This is the export you will use 95 % of the time.
exports.ob_notify:show({ title = 'Vehicle stored' })| Parameter | Type | Description |
|---|---|---|
title |
string |
Required. The main text |
description |
string |
Second line. Anything in backticks comes out monospaced |
type |
string |
success · error · warning · info · neutral. Defaults to neutral |
icon |
string |
Icon name. Falls back to the one for the type |
label |
string |
Uppercase header above the title |
duration |
number |
Milliseconds. If missing, calculated from the text length |
id |
string |
Same id = it replaces instead of stacking |
sound |
boolean |
Forces the sound even when disabled in config |
Returns the id — the one you passed, or a generated one.
Example — confirming a server action:
RegisterNetEvent('mygarage:client:stored', function(plate)
exports.ob_notify:show({
title = 'Vehicle stored',
description = 'Sultan RS · `' .. plate .. '`',
type = 'success',
icon = 'car'
})
end)If all you need is a title, pass the string directly:
exports.ob_notify:show('You are now on duty')hide(id)
Closes a notification before its time runs out.
exports.ob_notify:hide('garage')| Parameter | Type | Description |
|---|---|---|
id |
string |
Required. The id you gave it when firing |
If that id is not on screen, nothing happens. No need to check first.
clear()
Empties the whole stack, queue included.
exports.ob_notify:clear()No parameters. Useful on death, on character switch, or when entering a fullscreen menu.
showTextUI(text, options)
Shows the key prompt. There is only ever one, by design: calling it again replaces whatever was there.
exports.ob_notify:showTextUI('Press [E] to open the garage', { icon = 'car' })| Parameter | Type | Description |
|---|---|---|
text |
string |
Required. Anything in brackets is drawn as a key |
options.icon |
string |
Icon on the left |
options.type |
string |
Colours the icon, same as notifications |
options.position |
string |
left · right · top · bottom. Defaults to config |
Example — showing it when approaching a zone:
local inside = false
CreateThread(function()
while true do
local near = #(GetEntityCoords(cache.ped) - vector3(215.0, -810.0, 30.0)) < 2.0
if near and not inside then
inside = true
exports.ob_notify:showTextUI('Press [E] to open the garage', { icon = 'car' })
elseif not near and inside then
inside = false
exports.ob_notify:hideTextUI()
end
Wait(250)
end
end)hideTextUI()
Hides it. No parameters, and it does not fail when none was open.
exports.ob_notify:hideTextUI()pressTextUI()
Presses the key as if the player had done it.
exports.ob_notify:pressTextUI()ob_notify watches the key on its own: when the player presses it, it sinks
without anyone doing anything. This export exists to confirm the action at a
different moment — for example when the server says yes, rather than when the
key goes down.
isTextUIOpen() → boolean
Tells you whether one is open.
if exports.ob_notify:isTextUIOpen() then
exports.ob_notify:hideTextUI()
endServer
Same names, with source in front. Nothing else changes.
show(source, data)
exports.ob_notify:show(source, {
title = 'Payday received',
type = 'success',
icon = 'money'
})| Parameter | Type | Description |
|---|---|---|
source |
number |
Required. The player id. -1 for everyone |
data |
table |
The same fields as on the client |
Example — notifying police only:
RegisterNetEvent('mydispatch:server:alert', function(street)
for _, player in ipairs(GetPlayers()) do
if isPolice(player) then
exports.ob_notify:show(tonumber(player), {
label = 'Dispatch',
title = 'Robbery in progress',
description = street,
type = 'warning'
})
end
end
end)broadcast(data)
To everyone connected. Equivalent to show(-1, data) but it reads better.
exports.ob_notify:broadcast({ title = 'Restart in 5 minutes', type = 'warning' })The rest
| Export | What it does |
|---|---|
hide(source, id) |
Closes one of that player's notifications |
clear(source) |
Empties their stack |
showTextUI(source, text, options) |
Shows them the TextUI |
hideTextUI(source) |
Hides it |
Events
If you prefer events over exports — say from a resource you do not want to couple — they do exactly the same.
TriggerClientEvent('ob_notify:show', source, { title = 'Hello' })
TriggerClientEvent('ob_notify:hide', source, 'garage')
TriggerClientEvent('ob_notify:clear', source)
TriggerClientEvent('ob_notify:textui:show', source, 'Press [E]', { icon = 'car' })
TriggerClientEvent('ob_notify:textui:hide', source)Replacing instead of stacking
This is the least used feature and the one that changes the result most. With
the same id, the notification is rewritten in place: a three-step process
takes one card, not three.
local function storeVehicle()
exports.ob_notify:show({
id = 'garage', title = 'Storing vehicle…',
type = 'neutral', icon = 'clock', duration = 30000
})
local ok = lib.callback.await('mygarage:store', false)
exports.ob_notify:show({
id = 'garage',
title = ok and 'Vehicle stored' or 'Could not store it',
type = ok and 'success' or 'error',
icon = ok and 'car' or 'alert',
duration = 4000
})
endWhile the process runs you do not know how long it will take. With
duration = 30000 the card waits; the final step replaces it with its normal
duration. With the default duration it would vanish halfway through.