Quick navigation

Go to

WebUI & HUD

WebUI notifications

Reusable WebUI toasts: local client notifications, server-targeted delivery, updating and dismissing, queue limits, positions and progress.

3 min read620 wordsMarkdown
On this page6 sections

open77_notifications displays resource-owned WebUI toasts. Client resources can create notifications directly; server resources can request them through the package's server interface.

The WebUI is transparent and never captures input. Copy is inserted with DOM textContent, queues are bounded, and notifications disappear automatically when their owner stops or reloads.

Source: open77_notifications.

Not the only toast in the build. Open77.hud.notify, log and menu write to Cyberpunk's own notification pipelines β€” see vanilla toasts. Reach for those when you want something that looks like the game's own popup and costs no dependency and no browser surface; reach for open77_notifications when you need to control colour, icon, duration, stacking or dismissal.

Add the dependency

resource "jobs"
version "1.0.0"
dependency "open77_notifications >=1.0.0"

client_script "client/main.lua"
server_script "server/main.lua"

dependency takes a resource name and, optionally, version constraints after a space (>=, <=, >, <, = / ==, against a 1-to-3-part number such as 1.0.0); a plain dependency "open77_notifications" is enough when any version will do. A server whose load list lacks the package refuses to start the resource, which is the point: a toast sent to a client without the package is dropped without a word. Declare it for a server-only resource too, since Open77.notifications.* renders through the package.

Exports cross isolated Lua VMs and therefore return a promise. Call them from a scheduler coroutine.

Local client notification

CreateThread(function()
    local promise, callError = Open77.exports.call("open77_notifications", "show", {
        id = "job_started",
        type = "success",
        title = "Mission acceptee",
        message = "Rendez-vous au garage de Kabuki.",
        icon = "JOB",
        position = "middle_left",
        durationMs = 5000,
        progress = true,
        color = "#54E38E",
        data = { mission = "garage_intro" },
    })
    assert(promise, callError)

    local result, awaitError = promise:await()
    assert(result and result.ok, awaitError or (result and result.error))
    print("notification handle", result.handle)
end)

Supported types are info, success, warning, and error. Each type supplies a default colour; color overrides it with a #RRGGBB value.

Update, dismiss, and clear

local function notifications(name, ...)
    local promise, reason = Open77.exports.call("open77_notifications", name, ...)
    assert(promise, reason)
    return promise:await()
end

CreateThread(function()
    local shown = notifications("show", {
        id = "download",
        type = "info",
        title = "Synchronisation",
        message = "Telechargement des donnees...",
        durationMs = 0, -- persistent until update/dismiss/clear
        progress = false,
    })

    Wait(3000)
    notifications("update", shown.handle, {
        type = "success",
        message = "Synchronisation terminee.",
        durationMs = 3500,
        progress = true,
    })

    -- notifications("dismiss", shown.handle)
    -- notifications("clear") removes every toast owned by this resource.
end)

setEnabled(false) clears and suppresses the caller's notifications. list() returns that caller's active entries; resources cannot inspect, update, or dismiss another owner's handles.

The read-only readiness() export returns {ready=boolean}. It becomes true only after the notification WebUI's readiness callback, and resets on resource teardown. Gameplay requiring an admitted warning should check readiness and then check the show result; disabled owners or full queues can still reject a notification. Readiness/acceptance indicate presentation admission, not proof of rendered pixels.

Server-targeted notification

Server resources use the owner-aware API built into the server Lua runtime. The resource name is attached by the runtime; scripts cannot impersonate another owner:

RegisterNetEvent("jobs:completed", function(jobId)
    local playerId = source
    -- Validate the authoritative job state before notifying the player.
    local id, reason = Open77.notifications.send(playerId, {
        type = "success",
        title = "Mission terminee",
        message = "Votre paiement a ete transfere.",
        icon = "E$",
        durationMs = 6000,
        position = "middle_left",
    })
    assert(id, reason)
end)

Server methods are:

Method Purpose
Open77.notifications.send(playerId, definition) Send to one authenticated session ID and return its owner-local ID.
Open77.notifications.broadcast(definition) Send to every connected player.
Open77.notifications.update(id, patch) Update a notification previously returned by this server resource.
Open77.notifications.dismiss(id) Remove one notification owned by this server resource.
Open77.notifications.clear([playerId]) Clear this owner's notifications for one player or everyone.

Server IDs are owner-scoped. Client resources never receive an API that can forge a server-owned toast. Server records expire with timed notifications and are cleared when their owner stops.

Definition reference

Field Meaning
id Optional stable owner-local ID, maximum 96 characters.
replace Replace an existing notification with the same id when true.
type / kind info, success, warning, or error; defaults to info.
title Optional heading, maximum 96 UTF-8 bytes.
message / text Required body, maximum 384 UTF-8 bytes.
icon Optional short textual badge, maximum 16 UTF-8 bytes.
position middle_left (default), top_left, top_center, top_right, bottom_left, bottom_center, or bottom_right.
durationMs / duration Lifetime in milliseconds. 0 is persistent; timed values are 750-120000.
progress Shows the lifetime bar when timed; defaults to true.
color Optional #RRGGBB accent override.
data Caller-owned serializable context returned by the removal event.

The client holds at most 32 notifications and at most eight per position. Adding a ninth toast to a position evicts its oldest toast. Only the notification owner can mutate its entries.

Events and test command

open77:notificationRemoved is emitted locally with handle, id, owner, reason, and data. Removal reasons include expired, dismissed, queue_limit, owner_stopped, and server cleanup.

Authenticated administrators can validate the complete server-to-client route with:

/notification.test success
/notification.test warning
/notification.test error

// For agents & LLMsthis page as Markdownllms.txtllms-full.txt

// Guides Β· Lua API

Search the docs

1,905 guides and functions indexed

Try