Device & lifecycle

Read device info and control the native app shell — loading splash, navigation, the launch page, and cache.

Read device info

Get device facts like playerId, deviceOS, versionName, or a permission status. createBdkNative() requests device info on init — read it with getDeviceInfo(), await bdk.ready(timeoutMs), or the deviceInfo event.

bdk.getDeviceInfo() returns the latest BdkDeviceInfo, or null if it hasn't arrived yet (for example, in a plain browser or before the first deviceInfo event).

BdkDeviceInfo fields (each string or null unless noted):

PropertyTypeDescription
playerIdstringOneSignal player id for push.
pushTokenstringDevice push token.
deviceModelstringDevice model name.
deviceOSstringOperating system.
deviceOSVersionstringOS version.
bdkReleasestring | numberBDK runtime release.
deviceLanguagestringDevice language.
deviceWidthstring | numberScreen width.
deviceHeightstring | numberScreen height.
versionNamestringHost app version name.
versionCodestring | numberHost app version code.
biometricsAvailablebooleanWhether biometric login is available.
smartLoginAvailablebooleanWhether smart login is available.
cameraPermissionStatusstringCamera permission state.
contactsPermissionStatusstringContacts permission state.
audiorecordPermissionStatusstringAudio-record permission state.
externalstoragePermissionStatusstringExternal-storage permission state.
locationPermissionStatusstringLocation permission state.
idfastringiOS advertising id. iOS only.

Wait for the value with await bdk.ready(timeoutMs), or subscribe to the deviceInfo event — at startup and after a permission prompt.

import { createBdkNative } from "@bdk/native/browser";

const bdk = createBdkNative();

const info = bdk.getDeviceInfo();
if (info) {
  console.log(info.playerId, info.deviceOS, info.versionName);
}

Detect the native app

Check whether your page is running inside the native app. Branch on it to enable native-only UI or fall back to web behavior.

bdk.isNative() returns true once device info is available, false otherwise.

isNative() reads false until device info arrives, so a check at page load takes the web branch even inside the app. await bdk.ready(timeoutMs) first — it resolves as soon as the device reports in, or null at the timeout — then branch.

const info = await bdk.ready(3000); // resolves early once the device reports in

if (info) {
  await bdk.device.vibrate();
} else {
  // web fallback
}

Hide the loading splash

Dismiss the loading splash once your page is ready. Use this in "manual" mode to control exactly when the UI appears; with the default removeLoading: "automatic" you don't need to call it.

bdk.app.removeLoading().

const bdk = createBdkNative({ removeLoading: "manual" });

// ...once your UI is mounted:
await bdk.app.removeLoading();

Restyle the loading splash

Change the appearance of the loading splash.

bdk.app.updateLoading(options). Recognized LoadingScreenOptions keys: splash_layer_url, splash_layer_width, splash_layer_top, splash_layer_left, and splash_section_background.

await bdk.app.updateLoading({
  splash_layer_url: "https://cdn.example.com/splash.png",
  splash_layer_width: "60%",
  splash_layer_top: "40%",
  splash_layer_left: "20%",
  splash_section_background: "#0B0B0B"
});

Go back

Navigate back, the equivalent of the native back action.

bdk.app.goBack().

await bdk.app.goBack();

Change the launch page

Set which URL the app opens on next launch, then clear it when done.

bdk.app.setLaunchPage(options) sets the alternate launch URL. bdk.app.resetLaunchPage() removes the override and restores the default.

await bdk.app.setLaunchPage({ url: "https://app.example.com/home" });

Vibrate the device

Trigger device haptics.

bdk.device.vibrate(options?).

await bdk.device.vibrate();

Read the device contacts

Fetch the device address book. Ask for the contacts permission first. For structured results and paging, use contacts.list.

bdk.device.getContacts().

The device address book arrives on the contacts event — an array of contacts, each with a name, phone number(s), and email(s) — not in the returned promise. Subscribe before you call.

bdk.on("contacts", (addressBook) => {
  console.log("contacts payload", addressBook);
});

await bdk.permissions.ask("contacts");
await bdk.device.getContacts();

Save and read cache values

Persist small values in native storage and read them back later — handy for flags like onboarding state.

bdk.device.saveToCache(options) and bdk.device.getFromCache(options).

The cached value arrives on the deviceVariable event as a DeviceVariableResult with the variable's name and its stored data value, not in the returned promise. Subscribe before you read. If the key was never stored, data is null.

await bdk.device.saveToCache({ key: "onboarded", value: "true" });

Lifecycle events reference

Subscribe with bdk.on(event, listener), which returns an unsubscribe function. The events:

  • deviceInfoBdkDeviceInfo. The shell reported device info; also feeds getDeviceInfo() and ready().
  • contacts. The device address book from device.getContacts() — an array of contacts, each with a name, phone number(s), and email(s).
  • deviceVariableDeviceVariableResult with the variable's name and its stored data value. A cached value from device.getFromCache(...).
  • backButtonPressedundefined. The hardware back button was pressed.

If a listener throws, the error surfaces once as a BdkError with code BDK_LISTENER_ERROR, delivered to your onError config callback and the error event.

const offDeviceInfo = bdk.on("deviceInfo", (info) => console.log(info.deviceModel));
const offContacts = bdk.on("contacts", (book) => console.log(book));
const offVariable = bdk.on("deviceVariable", ({ name, data }) => console.log(name, data));
const offBack = bdk.on("backButtonPressed", () => console.log("back pressed"));

// call the returned functions to stop listening
offDeviceInfo();
offContacts();
offVariable();
offBack();

Pick a contact

Open the system contact picker. It does not prompt for address-book permission. On iOS, pass multiple: true to pick more than one.

Each item is a BdkContact with structured phones and emails.

This feature can be switched off in a given app build — check await bdk.capabilities.has("contacts.picker") before showing the picker. See Detect features. If the feature is off, the call throws.

PropertyTypeDescription
multiplebooleanPick more than one contact. iOS only.
import { createBdkNative } from "@bdk/native/browser";

const bdk = createBdkNative();

// The picker throws when the feature is off in this build — check first.
if (await bdk.capabilities.has("contacts.picker")) {
  const result = await bdk.contacts.pick();

  if (!result.ok) {
    console.error(result.code, result.message);
  } else {
    for (const contact of result.contacts) {
      console.log(contact.name, contact.phones, contact.emails);
    }
  }
}

List contacts

Read a page of the device address book. This needs contacts permission; the picker above does not. Native accepts limit 1–200 and pages with offset; the result has access (full or limited), total, hasMore, and nextOffset.

Check await bdk.capabilities.has("contacts.book") before showing the list. If the feature is off, the call throws.

PropertyTypeDescription
limitnumberPage size, 1–200.
offsetnumberZero-based start of the page.
// list() throws when the feature is off in this build — check first.
if (await bdk.capabilities.has("contacts.book")) {
  const result = await bdk.contacts.list({ limit: 50, offset: 0 });

  if (!result.ok) {
    console.error(result.code, result.message);
  } else {
    console.log(result.access, result.total, result.contacts);
    if (result.hasMore && result.nextOffset != null) {
      const next = await bdk.contacts.list({
        limit: 50,
        offset: result.nextOffset
      });
      if (next.ok) console.log(next.contacts);
    }
  }
}