@grabjs/superapp-sdk
    Preparing search index...

    Core Concepts

    SDK methods communicate with the native Grab SuperApp via JSBridge. They only work when your page is running inside the Grab SuperApp WebView. Calling a method outside that environment returns { status_code: 501 }.

    Every SDK method returns a bridge response object with an HTTP-style status_code. SDK methods never throw — use type guards instead of try/catch.

    import { CameraModule, isSuccess, isError } from '@grabjs/superapp-sdk';

    const camera = new CameraModule();
    const response = await camera.scanQRCode({ title: 'Scan Payment QR' });

    if (isSuccess(response)) {
    switch (response.status_code) {
    case 200:
    console.log('QR Code scanned:', response.result.qrCode);
    break;
    case 204:
    // operation completed with no content
    break;
    }
    } else if (isError(response)) {
    // response.error: string is guaranteed
    switch (response.status_code) {
    case 403:
    // call IdentityModule.authorize() then ScopeModule.reloadScopes() before retrying
    break;
    default:
    console.error(`Error ${response.status_code}: ${response.error}`);
    }
    }

    The SDK uses HTTP-style status codes for all responses:

    Code Type Description
    200 OK Request successful, result contains response data
    204 No Content Request successful, no data returned
    302 Redirect Redirect in progress
    400 Bad Request Invalid request parameters
    401 Unauthorized Authentication required
    403 Forbidden Insufficient permissions for this operation
    404 Not Found Resource not found
    424 Failed Dependency Underlying native request failed
    426 Upgrade Required Requires newer Grab app version
    500 Internal Error Unexpected SDK error
    501 Not Implemented Method requires Grab SuperApp environment

    Type guards narrow the response type so TypeScript knows which fields are available:

    Guard Matches
    isSuccess(r) 200, 204
    isOk(r) 200
    isNoContent(r) 204
    isRedirection(r) / isFound(r) 302
    isClientError(r) 400, 401, 403, 404, 424, 426
    isServerError(r) 500, 501
    isError(r) any 4xx or 5xx
    import { isSuccess, isOk, isNoContent, isError } from '@grabjs/superapp-sdk';

    if (isSuccess(response)) {
    // narrow further if needed
    if (isOk(response)) console.log(response.result);
    if (isNoContent(response)) console.log('done, no data');
    }

    if (isError(response)) {
    // response.error: string is guaranteed here
    console.error(response.error);
    }

    Some modules provide streaming methods for real-time data (location updates, media events). Subscribe to receive values over time:

    import { LocationModule, isSuccess } from '@grabjs/superapp-sdk';

    const location = new LocationModule();

    const subscription = location.observeLocationChange().subscribe({
    next: (response) => {
    if (isSuccess(response)) console.log(response.result);
    },
    complete: () => console.log('Stream ended'),
    });

    // Always unsubscribe when done to conserve battery and resources
    subscription.unsubscribe();

    You can also await a stream method directly to get its first value.