Skip to content

NssClient ​

NUI-to-Lua communication bridge. Sends messages from JavaScript to the Lua client via XHR and receives push events from Lua via window.postMessage. NUI

Getting Started ​

NssClient is the primary communication channel between your NUI (browser) and your Lua client script.

js
import {NssUiApi} from "nui://nss_libs/ui/NssUiApi.js";

const RESOURCE_NAME = 'my_resource';
const nss_ui_api = new NssUiApi(RESOURCE_NAME);

nss_ui_api.load([NssUiApi.NssClient]).then((components) => {
    const nss_client = new components.NssClient(RESOURCE_NAME);

    nss_client.on('show', (data) => {
        // Handle show event from Lua
    });

    nss_client.post('ready');
});

Constructor ​

new NssClient(resource_name) ​

Creates a new NUI client bridge.

ParamTypeDefaultDescription
resource_namestring—The exact name of your resource folder. Used to construct the XHR URL

WARNING

The resource_name must exactly match your resource folder name — it's used to construct the XHR URL (https://<resource_name>/<event_name>).

js
const nss_client = new NssClient('my_resource');

Methods ​

.post(event_name, data?, cb?, loading_indicator_target_el?) ​

Sends a message to the Lua client via XHR POST.

ParamTypeDefaultDescription
event_namestring—The event name (maps to RegisterNUICallback on the Lua side)
dataobject{}The payload to send
cbfunctionundefinedCallback fired when Lua responds. A unique response_event_type is added to the request and a 30s timeout is set
loading_indicator_target_elHTMLElementundefinedIf provided, a loading indicator is shown on this element while waiting

Returns undefined

js
// Fire-and-forget
nss_client.post('player_action', {action: 'sit'});
js
// With response callback
nss_client.post('load_data', {id: 42}, (response) => {
    console.log('Received:', response);
});
js
// With loading indicator
nss_client.post('load_data', {id: 42}, (response) => {
    renderData(response);
}, document.getElementById('content-area'));

.on(event_name, cb) ​

Registers a listener for events pushed from Lua to NUI (via SendNUIMessage).

ParamTypeDefaultDescription
event_namestring—The event name to listen for
cbfunction—Callback receiving the event data

Returns undefined

WARNING

Only one callback per event name is allowed. Use a wrapper to dispatch to multiple handlers.

js
nss_client.on('show', (data) => {
    document.body.style.display = 'block';
});

nss_client.on('update_inventory', (data) => {
    renderItems(data.items);
});

.close(data?) ​

Shorthand for post('close', data). Commonly used to tell Lua to close the NUI focus.

ParamTypeDefaultDescription
dataobjectundefinedOptional payload sent with the close event

Returns undefined

js
nss_client.close();
js
nss_client.close({reason: 'user_cancelled'});

.setLoadingIndicatorDelay(ms) ​

Sets the delay before the loading indicator appears. Prevents flicker for fast responses.

ParamTypeDefaultDescription
msnumber500Delay in milliseconds

Returns undefined

js
nss_client.setLoadingIndicatorDelay(200); // Show indicator after 200ms

Mock for Local Development ​

NssClient.mockFactory(resource_name) ​

Creates a mock client for testing NUI in a regular browser without RedM.

ParamTypeDefaultDescription
resource_namestring—The resource name

Returns Promise<NssClientMock> — a mock client instance.

js
const nss_client = await NssClient.mockFactory('my_resource');

.simulateClientToNuiEvent(event_name, data) ​

Simulates an event from Lua to NUI (like SendNUIMessage).

ParamTypeDefaultDescription
event_namestring—The event name
dataobject—The event payload

Returns undefined

js
mock_client.simulateClientToNuiEvent('show', {title: 'Test Dialog'});

.listenPostForResponseSimulation(event_name, cb, timeout_in_ms?) ​

Intercepts post() calls and returns simulated responses.

ParamTypeDefaultDescription
event_namestring—The event to intercept
cbfunction—Function receiving request data and returning response data
timeout_in_msnumber100Simulated response delay

Returns undefined

js
mock_client.listenPostForResponseSimulation('load_data', (request) => {
    return {items: ['Revolver', 'Lasso'], success: true};
}, 500);

// Now calling post('load_data', ...) will receive the simulated response after 500ms

Lua Client Side ​

On the Lua side, use exports.nss_libs:getNssClientApi() to create the bridge.

ParamTypeDefaultDescription
register_cbfunction—Wrapper for RegisterNUICallback(event_name, callback)
send_cbfunction—Wrapper for SendNUIMessage(response)

Important

The wrappers are required because RegisterNUICallback and SendNUIMessage must be called from your resource, not from nss_libs.

lua
---@param event_name string
---@param callback fun(request: NssClientRequest):NssClientResponse
local register_nui_callback_wrapper = function(event_name, callback)
    RegisterNUICallback(event_name, callback)
end

---@param response NssClientResponse
local send_nui_message_wrapper = function(response)
    SendNUIMessage(response)
end

---@type NssClientApi
local NUI_CLIENT = exports.nss_libs:getNssClientApi(register_nui_callback_wrapper, send_nui_message_wrapper)

-- Listen for NUI events
NUI_CLIENT.on('player_action', function(request)
    -- Handle action
    return {success = true}
end)

-- Push data to NUI
NUI_CLIENT.send('update_inventory', {items = player_items})

Events / Callbacks ​

  • Response callback — fires when Lua responds to a post() call with cb parameter. Times out after 30 seconds.
  • Push events — registered via on(), fired when Lua calls SendNUIMessage / NUI_CLIENT.send().

CSS ​

None. NssClient has no visual representation.

Dependencies ​

  • NssUiComponentInterface — base class (no NssResponsive dependency).
  • NssLoadingIndicator — used internally when loading_indicator_target_el is provided.

Things to Know ​

TIP

When using cb on post(), a unique response_event_type is automatically added to the request data. Lua must include this value in the response for the callback to fire.

DANGER

Response callbacks timeout after 30 seconds with a console error if no response is received.

  • NssClientMock replaces post() with local simulation — on() events still work via window.postMessage.

NIGHTSHIFT STUDIO Documentation