Skip to content
NeekoGta edited this page Jun 17, 2026 · 1 revision

JS API

The browser side exposes a cef JavaScript bridge.

Listen for server events

cef.on("hud:update", (health, armour, money) => {
    console.log("HUD update", health, armour, money);
});

Pawn:

CEF_EmitEvent(playerid, browserid, "hud:update", CEF_INT(100), CEF_INT(50), CEF_INT(2500));

Emit events to Pawn

JavaScript:

cef.emit("login:submit", "Neeko", "secret");

Pawn:

CEF_RegisterEvent("login:submit", "OnLoginSubmit", Argument_String, Argument_String);

forward OnLoginSubmit(playerid, const username[], const password[]);
public OnLoginSubmit(playerid, const username[], const password[])
{
    printf("Login attempt: %s", username);
    return 1;
}

Built-in events

cef:escape_menu

When the server enables custom ESC mode:

CEF_SetEscapeMenuMode(playerid, CEF_ESCAPE_MENU_CUSTOM);

JavaScript can listen with:

cef.on("cef:escape_menu", (visible) => {
    document.body.classList.toggle("pause-open", visible);
});

Defensive JS wrapper

For development, you can guard against loading the page in a normal browser:

window.cef = window.cef || {
    on(name, callback) {
        console.warn(`[mock cef.on] ${name}`);
    },
    emit(name, ...args) {
        console.warn(`[mock cef.emit] ${name}`, args);
    }
};

This lets you preview UI in Chrome/Edge without crashing because cef is undefined.

Recommended event bridge file

// js/cef-bridge.js
export function onCef(name, callback) {
    if (!window.cef || typeof window.cef.on !== "function") {
        console.warn(`CEF bridge unavailable for event: ${name}`);
        return;
    }

    window.cef.on(name, callback);
}

export function emitCef(name, ...args) {
    if (!window.cef || typeof window.cef.emit !== "function") {
        console.warn(`CEF bridge unavailable for emit: ${name}`, args);
        return;
    }

    window.cef.emit(name, ...args);
}

Server-side validation

Never trust JS events. Always validate everything in Pawn/server-side code.

Clone this wiki locally