gta6/prompts
ui
Freebeginnerui

Notification System: Typed Toasts

A reusable typed-toast notification system (success/error/info/warning) with client and server exports for other resources.

NON-TESTÉ — the reference Lua is syntax-validated, not run in a live FiveM server. Adapt and test on your own dev server before shipping.
Est. Lua
~58 loc
Claude
Claude Opus 4.x / Sonnet 4.x
Validation
syntax-validated
Updated
2026-06-24

Description

A drop-in typed toast notification resource. It renders four styles — success, error, info, warning — as stacked toasts via NUI, and exposes clean exports so any other resource can fire a toast on the client (exports['toasts']:notify(...)) or from the server to a specific player (exports['toasts']:notifyPlayer(src, ...)). A server-wide notifyAll and a /announce console command round it out.

Prompt Template

You are writing a FiveM resource for a generic toast notification system (no
framework dependency). Produce ONE file containing both client.lua and
server.lua, separated by clear "-- ===== client.lua =====" and
"-- ===== server.lua =====" banners.

CLIENT requirements:
1. A local notify(type, message, duration) that whitelists type against
   { success, error, info, warning } and falls back to "info" for anything else.
2. SendNUIMessage({ action='toast', type=, message=, duration= }).
3. exports('notify', notify) so other resources call
   exports['{{RESOURCE}}']:notify('success', 'Saved!').
4. RegisterNetEvent('toasts:show', ...) as the SERVER->CLIENT bridge — without
   this the server cannot reach the client.
5. A /testtoast command taking the type as arg[1].

SERVER requirements:
1. notifyPlayer(playerId, type, message, duration) -> TriggerClientEvent('toasts:show', playerId, ...).
2. notifyAll(...) using -1 as the target.
3. Export both; add an /announce CONSOLE-only command (source == 0).

Return only Lua. No prose, no markdown fences.

Expected Output

The reference Lua lives at content/expected-outputs/ui/02-notification-system.lua. It implements the client notify with a type whitelist and exports('notify'), the toasts:show net-event bridge, and server-side notifyPlayer / notifyAll exports plus an /announce console command. In fxmanifest.lua it is a client_script, a server_script, and a ui_page for the toast markup.

02-notification-system.lua59 lines
-- 02-notification-system.lua
-- Typed toast notification system (success / error / info / warning).
-- Client exposes an export + NUI bridge; server can push to any player.

-- ===== client.lua =====

-- Queue a typed toast onto the NUI layer.
local function notify(notifType, message, duration)
    local valid = { success = true, error = true, info = true, warning = true }
    if not valid[notifType] then
        notifType = "info"
    end

    SendNUIMessage({
        action   = "toast",
        type     = notifType,
        message  = tostring(message),
        duration = tonumber(duration) or 4000,
    })
end

-- Export so other resources call exports['toasts']:notify('success', 'Saved!').
exports("notify", notify)

-- Server -> client bridge: a server script triggers this for a target player.
RegisterNetEvent("toasts:show", function(notifType, message, duration)
    notify(notifType, message, duration)
end)

-- Quick test command so you can verify each style in-game.
RegisterCommand("testtoast", function(_, args)
    local t = args[1] or "info"
    notify(t, "This is a " .. t .. " toast.", 4000)
end, false)

-- ===== server.lua =====

-- Server-side helper: push a typed toast to a specific player id.
local function notifyPlayer(playerId, notifType, message, duration)
    if not playerId then return end
    TriggerClientEvent("toasts:show", playerId, notifType, message, duration)
end

-- Export it so server resources call exports['toasts']:notifyPlayer(src, ...).
exports("notifyPlayer", notifyPlayer)

-- Broadcast a toast to everyone (e.g. server announcements).
local function notifyAll(notifType, message, duration)
    TriggerClientEvent("toasts:show", -1, notifType, message, duration)
end

exports("notifyAll", notifyAll)

-- Example: announce server-wide via a console/admin command.
RegisterCommand("announce", function(source, args)
    if source ~= 0 then return end -- console only
    notifyAll("warning", table.concat(args, " "), 8000)
end, true)

Known Failure Modes

  • Missing net-event bridge — Claude writes the server TriggerClientEvent but no RegisterNetEvent('toasts:show') client-side, so nothing fires.
  • Unvalidated type — passing the raw type into a class name lets a typo kill styling; whitelist and fall back to info.
  • Wrong export syntax — FiveM uses exports['name']:fn(...), not exports.name.fn(...).
  • Spammy toasts — without a duration cap a flood of toasts stacks forever; pass and respect a duration.

Integration Notes

  • Split the banners into real client.lua and server.lua files; list both in fxmanifest.lua along with the ui_page and files {}.
  • No framework needed — works on ESX, QBCore or standalone.
  • Test: /testtoast success, /testtoast error, then from another resource call exports['toasts']:notify('info','hi') to confirm cross-resource use.

Profit Potential

$100–$1200/mo on Tebex (expected ~$300). [INFERRED] low end of the $50-389 band (signal-scraper tebex_snapshot, median seller $11.85K/mo, n=100); typed-toast systems are a commodity yet every resource needs one, so steady low-ticket volume.

Trend Signal

stable — [INFERRED] HUD/UI utilities are always-needed but commoditized.

Sales Angle

Position as drop-in notification infrastructure other resources depend on — framework-agnostic and bundle-friendly. Recommend $59 on Tebex.

Difficulty & Ship Time

beginner · ships in 2-4h.