Script integration
Custom apps

Custom Apps

See the custom apps exports for adding the app to the tablet. We recommend using our custom app template (opens in a new tab) to get started with creating custom apps.

Imported data

When the app gets loaded on the tablet, a few functions and data are imported into the globalThis object.

resourceName

The resource name of the app

appName

The name of the app

settings

The tablet settings

onNuiEvent

A function to listen for NUI events sent via SendCustomAppMessage

globalThis.onNuiEvent(event: string, callback: (data: any) => void): void

onSettingsChange

Listen for settings changes

globalThis.onSettingsChange(callback: (settings: any) => void): void

fetchNui

Fetch data from the script

globalThis.fetchNui(event: string, data?: any, scriptName?: string): Promise<any>

setApp

Open another app

globalThis.setApp(app: string): void

closeApp

Close the app

globalThis.closeApp(): void

setPopUp

Show a popup

type PopUp = {
    id?: number;
 
    title: string;
    description: string;
    vertical?: boolean;
 
    inputs?: PopUpInput[];
    input?: PopUpInput;
    textareas?: PopUpTextarea[];
    textarea?: PopUpTextarea;
 
    attachment?: {
        src: string;
    };
    buttons: {
        title: string;
        cb?: () => void;
        disabled?: boolean;
        bold?: boolean;
 
        color?: 'red' | 'blue';
    }[];
};
 
globalThis.setPopUp(data: PopUp): void

setFullScreenImage

Show a full screen image

globalThis.setFullScreenImage(src: string): void

setContextMenu

Show a context menu

type Contextmenu = {
    id?: number;
 
    title?: string;
    buttons: {
        title: string;
        color?: 'red' | 'blue';
        disabled?: boolean;
        cb?: () => void;
    }[];
};
 
globalThis.setContextMenu(data: Contextmenu): void

setControlCentreVisible

Show or hide the control centre

globalThis.setControlCentreVisible(visible: boolean): void

setGallery

Select an image or video from the gallery

type GalleryData = {
    id?: number;
 
    includeVideos?: boolean;
    includeImages?: boolean;
    allowExternal?: boolean;
    multiSelect?: boolean;
 
    onSelect: (data: PhotoData) => void;
};
 
type PhotoData = {
    id: number;
    src: string;
    timestamp?: number;
    type?: 'string';
    favourite?: boolean;
    isVideo?: boolean;
    size?: number;
    duration?: number;
};
 
globalThis.setGallery(data: GalleryData): void

setColorPicker

Select a color

type ColorPickerData = {
    id?: number;
 
    defaultColor?: string;
    onSelect: (color: string) => void;
    onClose?: (color: string) => void;
};
 
globalThis.setColorPicker(data: ColorPickerData): void

setIndicatorVisible

Show or hide the indicator

globalThis.setIndicatorVisible(visible: boolean): void

saveToGallery

saveToGallery: (url: string, size?: number, type?: 'screenshot' | 'selfie' | 'import', shouldLog?: boolean) => Promise<number | false>

uploadMedia

uploadMedia: (uploadType: 'Video' | 'Image' | 'Audio', blob: Blob) => Promise<string>

createGameRender

GameRender
interface GameRender {
    quality: number
    xOffset: number
    yOffset: number
    recorder: MediaRecorder | undefined
    recording: boolean
    destroyed: boolean
    canvas: HTMLCanvasElement | null
    gl: WebGLRenderingContext | null
    program: WebGLProgram | null
    paused: boolean
    viewport: {
        x: number
        y: number
        width: number
        height: number
    }
    canvasSize: {
        width: number
        height: number
    }
    animationFrame: number | null
    mainTexture: WebGLTexture | null
    hasPrevFrame: boolean
    prevTextures: WebGLTexture[]
    prevBuffers: WebGLFramebuffer[]
 
    pause(): void
    resume(): void
    resize(width: number, height: number): void
    resizeByAspect(ratio: number): void
    setQuality(quality: number): void
    setXOffset(offset: number): void
    setYOffset(offset: number): void
    destroy(keepCanvas?: boolean): void
    takePhoto(): Promise<Blob>
    startRecording(cb: (blob: Blob) => void): MediaRecorder | undefined
    render(): void
}
createGameRender: (canvas: HTMLCanvasElement) => GameRender | undefined

getMicrophoneStream

getMicrophoneStream: () => Promise<MediaStream | undefined>

releaseMicrophoneStream

releaseMicrophoneStream: () => void

listenToNearbyVoices

listenToNearbyVoices: (audioCtx: AudioContext, destination: MediaStreamAudioDestinationNode) => void

stopListeningToNearbyVoices

stopListeningToNearbyVoices: () => void