starti.app
SDK Reference

App

Control core app behavior including navigation, UI chrome, domain routing, device info, and screen options.

Access: startiapp.App

Methods

brandId(): Promise<string>

Returns the brand identifier of the app. The result is cached after the first call.

Returns: Promise<string> —The brand ID string.

Example:

const brandId = await startiapp.App.brandId();
// "example-brand"

deviceId(): Promise<string>

Returns a unique identifier for the current app installation. The ID changes if the user uninstalls and reinstalls the app. The result is cached after the first call.

Returns: Promise<string> — The installation ID (UUID format).

Example:

const deviceId = await startiapp.App.deviceId();
// "00000000-0000-0000-0000-000000000000"

version(): Promise<string>

Returns the app version string. The version format is major.minor.patch:

  • Major — a counter that increases when the minor number reaches 1000.
  • Minor — represents a specific commit in the starti.app codebase.
  • Patch — the build number, typically used when configuration or build-related changes are made without code changes.

Returns: Promise<string> — The version string.

Example:

const version = await startiapp.App.version();
// "4.28.1"

platform

A read-only property that returns the platform the app is running on.

Returns: string"android", "ios", or "web".

Example:

const platform = startiapp.App.platform;
// "android" | "ios" | "web"

isStartiappLoaded(): boolean

Returns whether the starti.app runtime has finished loading.

Returns: booleantrue if the SDK ready event has fired.

Example:

if (startiapp.App.isStartiappLoaded()) {
  console.log("SDK is ready");
}

supports(capability: AppCapability): boolean

Returns whether the app your page is running in is new enough for a given capability.

Users update the app on their own schedule, so a page can be running inside an older version that does not have every feature yet. The SDK checks this for you: a method that depends on a newer app falls back to something sensible, so calling it is always safe — each method's description says what it does instead.

Ask directly when the page should look different — for example to leave out a sign-in choice the app in front of you cannot carry out yet.

Parameters:

ParameterTypeRequiredDescription
capabilityAppCapabilityYesThe capability to check

Returns: booleantrue if the app supports it. Always false outside the app, where there is no app version to compare against.

Example:

if (startiapp.App.supports("signInOptions")) {
  showMitIdWithSsnButton();
}

addInternalDomain(domain: string): Promise<void>

For a practical guide to domain handling — including when to use handleAllDomainsInternally() and the difference between the in-app browser and the device's browser — see Handle Domains.

Registers a domain as internal. Internal domains are loaded inside the app's webview.

Parameters:

ParameterTypeRequiredDescription
domainstringYesThe domain to register as internal

Returns: Promise<void>

Example:

await startiapp.App.addInternalDomain("example.com");

removeInternalDomain(domain: string): Promise<void>

Removes a domain from the internal domains list.

Parameters:

ParameterTypeRequiredDescription
domainstringYesThe domain to remove

Returns: Promise<void>

Example:

await startiapp.App.removeInternalDomain("example.com");

getInternalDomains(): Promise<string[]>

Returns the list of registered internal domains.

Returns: Promise<string[]> —Array of internal domain strings.

Example:

const domains = await startiapp.App.getInternalDomains();
console.log(domains);
// ["example.com", "api.example.com"]

addExternalDomains(...domains: RegExp[]): Promise<void>

Registers domains as external using regex patterns. External domains open in the in-app browser.

Parameters:

ParameterTypeRequiredDescription
...domainsRegExp[]YesOne or more regex patterns matching external domains

Returns: Promise<void>

Example:

await startiapp.App.addExternalDomains(/example\.com/, /other\.org/);

removeExternalDomains(...domains: RegExp[]): Promise<void>

Removes domains from the external domains list.

Parameters:

ParameterTypeRequiredDescription
...domainsRegExp[]YesThe regex patterns to remove

Returns: Promise<void>

Example:

await startiapp.App.removeExternalDomains(/example\.com/);

getExternalDomains(): Promise<RegexDto[]>

Returns the list of registered external domain patterns.

Returns: Promise<RegexDto[]> —Array of regex pattern objects.

Example:

const externalDomains = await startiapp.App.getExternalDomains();
console.log(externalDomains);
// [{ pattern: "example\\.com", flags: "" }]

handleAllDomainsInternally(): Promise<void>

Treats all domains as internal, except those explicitly added as external. This is a session-only setting and resets on app restart.

Returns: Promise<void>

Example:

await startiapp.App.handleAllDomainsInternally();

restoreDefaultDomainHandling(): Promise<void>

Restores the default domain handling behavior where unknown domains are treated as external.

Returns: Promise<void>

Example:

await startiapp.App.restoreDefaultDomainHandling();

openExternalBrowser(url: string): Promise<void>

Opens a URL in the device's system browser.

Parameters:

ParameterTypeRequiredDescription
urlstringYesThe URL to open

Returns: Promise<void>

Example:

await startiapp.App.openExternalBrowser("https://example.com");

setStatusBar(options: SetStatusBarOptions): void

Configures the status bar appearance.

Options are merged onto the current status bar configuration, so you can update a single property at a time without resetting the rest. advancedSafeAreaOptions is merged recursively (per side, then per property).

Set darkContent: "auto" to let the app pick the content colour automatically from the configured safe area background colour's brightness. "auto" does not inspect the actual pixels or CSS background behind the status bar. If you remove the safe area, set darkContent explicitly to true or false so the status bar stays readable over your page content.

Parameters:

ParameterTypeRequiredDescription
optionsSetStatusBarOptionsYesStatus bar configuration (partial — merged onto the current options)

Example:

// Full configuration
startiapp.App.setStatusBar({
  hideText: false,
  darkContent: true,
  removeSafeArea: false,
  safeAreaBackgroundColor: "#ffffff",
});

// Update only the content colour — everything else is kept
startiapp.App.setStatusBar({ darkContent: "auto" });

hideStatusBar(): Promise<void>

Hides the device status bar.

Returns: Promise<void>

Example:

await startiapp.App.hideStatusBar();

showStatusBar(): Promise<void>

Shows the device status bar.

Returns: Promise<void>

Example:

await startiapp.App.showStatusBar();

setSafeAreaBackgroundColor(color: string): Promise<void>

Sets the background color of the safe area (notch / home indicator region).

Only the background colour changes. The content (text/icon) colour follows the darkContent setting: when it is "auto" (the default) the content colour is recomputed from the new background's brightness, and an explicit true/false choice is left untouched.

Parameters:

ParameterTypeRequiredDescription
colorstringYesCSS color value

Returns: Promise<void>

Example:

await startiapp.App.setSafeAreaBackgroundColor("#000000");

setSpinner(options: SpinnerOptions): Promise<void>

Configures the navigation loading spinner. This is particularly useful for traditional multi-page applications where clicking a link loads an entirely new HTML page. Since the app does not show a progress bar or other loading indicator during page navigation, the spinner makes it clear that new content is being loaded. By default, the spinner only appears after 250 milliseconds, so it stays hidden if the page loads quickly.

Parameters:

ParameterTypeRequiredDescription
optionsSpinnerOptionsYesSpinner configuration

Returns: Promise<void>

Example:

await startiapp.App.setSpinner({
  show: true,
  color: "#3498db",
  afterMilliseconds: 300,
  excludedDomains: ["cdn.example.com"],
});

showSpinner(options?: SpinnerOptions): Promise<void>

Shows the navigation loading spinner, optionally with configuration.

Parameters:

ParameterTypeRequiredDescription
optionsSpinnerOptionsNoOptional spinner configuration

Returns: Promise<void>

Example:

await startiapp.App.showSpinner();

// With options
await startiapp.App.showSpinner({
  show: true,
  color: "#e74c3c",
  afterMilliseconds: 500,
  excludedDomains: [],
});

hideSpinner(): Promise<void>

Hides the navigation loading spinner.

Returns: Promise<void>

Example:

await startiapp.App.hideSpinner();

pushOptions(options: InitializeParams): void

Pushes a set of UI options onto the options stack. This lets you temporarily override app options and restore them later with popOptions().

Parameters:

ParameterTypeRequiredDescription
optionsInitializeParamsYesThe options to push

Example:

startiapp.App.pushOptions({
  allowZoom: false,
  allowRotation: false,
  statusBar: {
    hideText: true,
    darkContent: false,
    removeSafeArea: true,
  },
});

popOptions(): void

Pops the most recent options from the options stack, restoring the previous state.

Example:

startiapp.App.popOptions();

enableScreenRotation(): Promise<void>

Enables the device screen to rotate with the device orientation.

Returns: Promise<void>

Example:

await startiapp.App.enableScreenRotation();

disableScreenRotation(): Promise<void>

Locks the screen orientation, preventing rotation.

Returns: Promise<void>

Example:

await startiapp.App.disableScreenRotation();

enableSwipeNavigation(): Promise<void>

Enables swipe gestures for back/forward navigation.

Returns: Promise<void>

Example:

await startiapp.App.enableSwipeNavigation();

disableSwipeNavigation(): Promise<void>

Disables swipe gestures for navigation.

Returns: Promise<void>

Example:

await startiapp.App.disableSwipeNavigation();

openSettings(): Promise<void>

Opens the device settings page for the app.

Returns: Promise<void>

Example:

await startiapp.App.openSettings();

setAppIcon(iconName: string): Promise<void>

Changes the app's home screen icon to one of the alternate icons that are built into the app. The available icons are configured in the starti.app Manager and bundled when the app is built.

Adding new icons requires publishing a new version of the app through Apple and Google's review process — you cannot add icons dynamically at runtime.

Parameters:

ParameterTypeRequiredDescription
iconNamestringYesName of the alternate icon (must match one returned by getAvailableIcons())

Returns: Promise<void>

Example:

const icons = await startiapp.App.getAvailableIcons();
// ["default", "dark-icon", "holiday-icon"]

await startiapp.App.setAppIcon("dark-icon");

getCurrentIcon(): Promise<string>

Returns the name of the currently active app icon.

Returns: Promise<string> —The current icon name.

Example:

const currentIcon = await startiapp.App.getCurrentIcon();
console.log(currentIcon);

getAvailableIcons(): Promise<string[]>

Returns the list of available alternate app icons.

Returns: Promise<string[]> —Array of icon names.

Example:

const icons = await startiapp.App.getAvailableIcons();
console.log(icons);
// ["default", "dark-icon", "holiday-icon"]

setSplashVariant(name: string | null): void

Chooses which of the brand's splash animations the app opens with, from the next launch onwards. Pass null to go back to the default one.

A brand that ships more than one splash animation names each of them in the starti.app Manager, under Alternative animations on the splash screen page — see Splash screen. This call selects one by that name. The choice is stored on the device, so it survives launches and app updates until your page changes it again; it is per installation, not per signed-in user, so clear it yourself on sign-out if that is what you mean.

This never affects the splash that is on screen right now. The app builds its splash before your page exists, so by the time you could answer "which animation?", one has already played. Call it when you learn something that should change the next opening — after a sign-in, say — not when you want the splash to change now.

Nothing is validated and nothing is reported back. A name the app does not have — an older build, or a variant the brand has since removed — opens the default animation rather than failing, which is what makes it safe to call during a rollout.

Parameters:

ParameterTypeRequiredDescription
namestring | nullYesThe variant name from the Manager, or null to go back to the default animation

Returns: void — the choice is recorded natively; there is nothing to await.

Requires: app version 4.229.0 — check with supports("splashVariants"). Older apps and browsers ignore the call, and those users keep seeing the default animation.

Example:

// After sign-in: returning users open on the short loop
startiapp.App.setSplashVariant("returning");

// After sign-out: back to the animation everyone else gets
startiapp.App.setSplashVariant(null);

getAppUrl(): Promise<string>

Returns the currently configured app URL.

Returns: Promise<string> —The app URL.

Example:

const url = await startiapp.App.getAppUrl();

setAppUrl(url: string): Promise<void>

Sets the app's base URL. The app will load this URL on next launch.

Parameters:

ParameterTypeRequiredDescription
urlstringYesThe URL to set

Returns: Promise<void>

Example:

await startiapp.App.setAppUrl("https://example.com");

resetAppUrl(): Promise<void>

Resets the app URL to its default value.

Returns: Promise<void>

Example:

await startiapp.App.resetAppUrl();

vibrate(intensity: VibrationIntensity): Promise<void>

For a practical guide to vibration — including CSS classes that trigger vibration without JavaScript — see Vibration.

Triggers device vibration with the specified intensity.

Parameters:

ParameterTypeRequiredDescription
intensityVibrationIntensityYesThe vibration intensity level

Returns: Promise<void>

Example:

// VibrationIntensity values: 0 = Low, 1 = Medium, 2 = High, 3 = Intense
await startiapp.App.vibrate(1); // Medium

requestReview(): Promise<void>

Prompts the user to rate the app in the app store. The system controls when and whether the prompt is actually shown.

This only works in the production version of the app (downloaded from the App Store or Google Play). During development and testing, the review prompt will not appear.

Returns: Promise<void>

Example:

await startiapp.App.requestReview();

requestAppTracking(): Promise<void>

Prompts the user to allow app tracking (iOS App Tracking Transparency).

The easiest way to trigger this is by adding a terms-and-conditions step to the Intro Flow in the starti.app Manager. The tracking prompt is then shown automatically when the user accepts the terms — no custom JavaScript needed.

Returns: Promise<void>

Example:

await startiapp.App.requestAppTracking();

Events

Fired when the app is navigating to a new page.

Event data: NavigatingPageEvent

Example:

startiapp.App.addEventListener("navigatingPage", (event) => {
  console.log("Navigating to:", event.detail.url);
  console.log("Opens external:", event.detail.opensExternalbrowser);
});

appInForeground

Fired when the app comes back to the foreground (e.g. user switches back to the app).

Event data: void

Example:

startiapp.App.addEventListener("appInForeground", () => {
  console.log("App is back in foreground");
  // Refresh data, reconnect sockets, etc.
});

splashHidden

Fired when the app's splash screen has gone and your page is what the user is looking at.

Sticky: a listener added after it happened still fires. That is the normal case rather than the exception — the splash is taken down within a frame or two of the SDK becoming ready, so even a listener added from your own ready handler can be too late, and being too late would look exactly like an event that never arrives.

Event data: void

Example:

startiapp.App.addEventListener("splashHidden", () => {
  // Nothing before now was on screen for the user to see.
  playTheOpeningAnimation();
});

splashAnimationCompleted

Fired when the splash screen's animation has played its last frame.

Only ever fired for a brand whose splash animation plays once — a looping one has no last frame — and it is independent of splashHidden: depending on the brand's splash settings the animation may finish well before the splash goes, or the splash may go first and this never fire at all. Sticky, like splashHidden.

Event data: void

Example:

startiapp.App.addEventListener("splashAnimationCompleted", () => {
  // Hand over from the splash artwork without cutting it off.
  revealTheHero();
});

Neither event is sent by an app shell older than the build that introduced them, and there is no capability to ask. Treat them as an enhancement rather than something to gate rendering on.


Types

AppCapability

The capabilities supports() can be asked about. Each one arrived in a specific app version; older apps answer false.

type AppCapability =
  // signIn() accepts an options argument (requireSsn, scope) — app 3.992.0
  | "signInOptions"
  // openSecureBrowser() presents the OS browser sheet over the app — app 4.184.0
  | "secureBrowser"
  // setStatusBar() state can be replaced as well as patched, which is what lets
  // popOptions() undo a pushOptions() — app 4.205.0
  | "statusBarState"
  // setSplashVariant() records which splash animation the next launch opens with — app 4.229.0
  | "splashVariants";
interface NavigatingPageEvent {
  url: string;
  opensExternalbrowser: boolean;
}

VibrationIntensity

enum VibrationIntensity {
  Low = 0,
  Medium = 1,
  High = 2,
  Intense = 3,
}

SetStatusBarOptions

Every property is optional. The app merges the properties you provide onto the current status bar settings, so you can change a single property at a time (for example only darkContent) without resetting the rest.

type SetStatusBarOptions = SafeAreaSideOptions & {
  hideText?: boolean;
  // true = dark content (for light backgrounds)
  // false = light content (for dark backgrounds)
  // "auto" (default) = chosen from the configured safe area background colour's brightness
  // If removeSafeArea is true, set this explicitly because web content is not inspected.
  darkContent?: boolean | "auto";
  advancedSafeAreaOptions?: AdvancedSafeAreaOptions;
};

SafeAreaSideOptions

type SafeAreaSideOptions = {
  removeSafeArea?: boolean; // defaults to false
  safeAreaBackgroundColor?: string; // defaults to "#FFFFFF"
};

AdvancedSafeAreaOptions

interface AdvancedSafeAreaOptions {
  top?: SafeAreaSideOptions;
  bottom?: SafeAreaSideOptions;
}

SpinnerOptions

interface SpinnerOptions {
  afterMilliseconds: number;
  show: boolean;
  color: string;
  excludedDomains: string[];
}

InitializeParams

interface InitializeParams {
  allowZoom?: boolean;
  allowRotation?: boolean;
  allowDrag?: boolean;
  allowScrollBounce?: boolean;
  allowHighligt?: boolean;
  allowSwipeNavigation?: boolean;
  spinner?: Partial<SpinnerOptions>;
  statusBar?: SetStatusBarOptions;
}

Prefer the Manager for these. All of these options can be configured for your brand under Initialization settings in the starti.app Manager, and that is the recommended place to set them — they then apply to your whole app with no code.

Options are resolved in four layers, each merged onto the one before it property by property:

LayerSet byChanged by
SDK defaultsThe SDK
Brand settingsInitialization settings in the ManagerA publish in the Manager, live within about 15 minutes
initialize()Your pageA release of your website
pushOptions()Your page, per screenAt runtime, and undone with popOptions()

Because the layers merge property by property, passing a partial object — say statusBar: { darkContent: true } — overrides only that property and keeps the rest of the brand's configuration. Set an option in code when it can only be decided at runtime, for example a status bar that follows the user's dark mode, or a screen that needs different gestures than the rest of the app.

Property-by-property merging of the nested statusBar and spinner objects only applies to brands that have initialization settings in the Manager. For a brand without them, passing a partial statusBar replaces the object wholesale.

RegexDto

interface RegexDto {
  pattern: string;
  flags: string;
}

On this page

MethodsbrandId(): Promise<string>deviceId(): Promise<string>version(): Promise<string>platformisStartiappLoaded(): booleansupports(capability: AppCapability): booleanaddInternalDomain(domain: string): Promise<void>removeInternalDomain(domain: string): Promise<void>getInternalDomains(): Promise<string[]>addExternalDomains(...domains: RegExp[]): Promise<void>removeExternalDomains(...domains: RegExp[]): Promise<void>getExternalDomains(): Promise<RegexDto[]>handleAllDomainsInternally(): Promise<void>restoreDefaultDomainHandling(): Promise<void>openExternalBrowser(url: string): Promise<void>setStatusBar(options: SetStatusBarOptions): voidhideStatusBar(): Promise<void>showStatusBar(): Promise<void>setSafeAreaBackgroundColor(color: string): Promise<void>setSpinner(options: SpinnerOptions): Promise<void>showSpinner(options?: SpinnerOptions): Promise<void>hideSpinner(): Promise<void>pushOptions(options: InitializeParams): voidpopOptions(): voidenableScreenRotation(): Promise<void>disableScreenRotation(): Promise<void>enableSwipeNavigation(): Promise<void>disableSwipeNavigation(): Promise<void>openSettings(): Promise<void>setAppIcon(iconName: string): Promise<void>getCurrentIcon(): Promise<string>getAvailableIcons(): Promise<string[]>setSplashVariant(name: string | null): voidgetAppUrl(): Promise<string>setAppUrl(url: string): Promise<void>resetAppUrl(): Promise<void>vibrate(intensity: VibrationIntensity): Promise<void>requestReview(): Promise<void>requestAppTracking(): Promise<void>EventsnavigatingPageappInForegroundsplashHiddensplashAnimationCompletedTypesAppCapabilityNavigatingPageEventVibrationIntensitySetStatusBarOptionsSafeAreaSideOptionsAdvancedSafeAreaOptionsSpinnerOptionsInitializeParamsRegexDto