fetchNui
Send NUI callbacks from the browser to the FiveM Lua client.
fetchNui is a utility function for sending NUI callbacks from the browser (JavaScript) to the FiveM Lua client. It wraps the native fetch API and targets the FiveM NUI callback endpoint.
Import
import { fetchNui } from '@repo/ui/utils/fetch'Signature
async function fetchNui<T = unknown>(
eventName: string,
data?: unknown,
mockData?: T
): Promise<T>Parameters
| Parameter | Type | Description |
|---|---|---|
eventName | string | The NUI callback name registered in Lua via RegisterNUICallback |
data | unknown | Optional data payload to send |
mockData | T | Optional mock data returned in development mode |
Returns
Promise<T> — The response from the Lua callback.
Usage
Basic Usage
import { fetchNui } from '@repo/ui/utils/fetch'
// Send a callback to Lua
const result = await fetchNui('getPlayerData')
// With payload
await fetchNui('updateSettings', { volume: 0.8, language: 'en' })With Mock Data (Development)
When running in development mode (import.meta.env.DEV), you can pass mock data that is returned immediately without making a network request. This allows you to develop NUI interfaces outside of FiveM.
const playerData = await fetchNui('getPlayerData', undefined, {
name: 'John Doe',
id: 1,
job: 'police',
})
// In dev mode: returns the mock data immediately
// In production: sends a real NUI callback to the Lua clientMock data is only used when import.meta.env.DEV is true (during vite dev). In production builds, the mock data parameter is ignored and real NUI callbacks are sent.
How It Works
Under the hood, fetchNui sends a POST request to the FiveM NUI callback URL:
https://{resourceName}/{eventName}The resourceName is obtained from window.GetParentResourceName(), which is provided by the FiveM NUI environment. When running outside FiveM (e.g., in a browser during development), it falls back to 'nui-frame-app'.
Corresponding Lua Code
On the Lua side, register a callback to handle the event:
RegisterNUICallback('getPlayerData', function(data, cb)
local playerData = {
name = GetPlayerName(PlayerId()),
id = GetPlayerServerId(PlayerId()),
}
cb(playerData)
end)Source
declare global {
interface Window {
GetParentResourceName: () => string
}
}
export async function fetchNui<T = unknown>(
eventName: string,
data?: unknown,
mockData?: T
): Promise<T> {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: JSON.stringify(data),
}
if (import.meta.env.DEV && mockData) return mockData
const resourceName = window.GetParentResourceName
? window.GetParentResourceName()
: 'nui-frame-app'
const resp = await fetch(`https://${resourceName}/${eventName}`, options)
const respFormatted = await resp.json()
return respFormatted
}