AppbrewDevelopers
Reference

Web SDK

Every method the in-webview Appbrew Web SDK exposes, with payload shapes.

The Web SDK is the JavaScript API a web page uses to call the Appbrew app it is running inside. For a walkthrough, start with the Web SDK guide. This page is the surface.

<script src="https://solutions.appbrew.tech/web-sdk/appbrew-sdk.js"></script>

The script defines window.appbrewSDK. It is untyped JavaScript with no build step and no npm package. It also leaves a helper named getRequestId on window, so avoid that name in your own code.

Methods

MethodReturnsWaits for the app
isApp()booleanno, synchronous
getUserDetails()Promise<UserDetails>yes, 5 s
addToCart(handle, variantId, quantity)Promise<CartResult>yes, 5 s
addMultipleItemsToCart(items)Promise<CartResult>yes, 5 s
gotoLink(link)Promise<undefined>no
goBackInApp()Promise<undefined>no
sendEvent(event, data)Promise<undefined>no

isApp() is synchronous. The three methods that do not wait are declared async, so they return a promise, but it resolves immediately with undefined and carries no information about whether the app acted. There is nothing useful to await.

Every method except isApp() returns undefined when the bridge is absent, after logging to the console. Check isApp() first.

isApp

isApp(): boolean

true when the app's bridge is present on the page. Equivalent to typeof window.appbrew !== 'undefined'.

getUserDetails

getUserDetails(): Promise<UserDetails | undefined>

Asks the app for the signed-in customer. Resolves within five seconds in every case, and never rejects.

The result is one of two shapes. On success the app sends every field below. On timeout the SDK synthesises { status: 'error', message: 'Could not fetch user details' } and nothing elseisLoggedIn, customerAccessToken, customer and tags are absent, not null. Branch on status before reading anything else.

type UserDetails =
  | {
      status: 'success'
      isLoggedIn: boolean
      customerAccessToken: string | null
      customer: Customer | null
      tags: string[]
    }
  | { status: 'error'; message: string }

The success arm:

Prop

Type

Customer:

Prop

Type

Address carries id, address1, address2, city, province, country, countryCodeV2, zip, firstName, lastName, and phone. Every one of them is string | null.

The app serves a cached profile and only fetches when the cache is empty, so an edit made elsewhere may not be reflected until the next fetch.

addToCart

addToCart(
  handle: string,
  variantId: string,
  quantity: number
): Promise<CartResult | undefined>

Adds one item to the app's cart. variantId is a Shopify variant global id. The handle is sent along but the app ignores it: items are added by variant.

type CartResult = { status: 'success' | 'error'; message: string }

status is 'error' only when the app did not confirm within five seconds. Success is weaker than it looks: the app replies once it has finished handling the request, and an error on its side still resolves as 'success'. A rejected or out-of-stock variant produces silence, and therefore a timeout. Re-read the cart rather than trusting either answer.

addMultipleItemsToCart

addMultipleItemsToCart(items: CartItem[]): Promise<CartResult | undefined>

Adds several items in one cart update. Same result shape and same timeout as addToCart.

type CartItem = {
  handle?: string        // ignored
  variantId: string
  quantity: number
  sellingPlanId?: string
  customAttributes?: Record<string, string> | Array<{ key: string; value: string }>
}
gotoLink(link: Link): Promise<undefined>

Hands navigation to the app. Returns before the app has done anything.

interface Link {
  kind: string
  value: string
  params?: Record<string, any>
  external?: boolean
}
kindvalueResult
productproduct handleNative product screen
collectioncollection handle, or a global idNative collection screen
cart'cart'The cart screen
screenscreen nameThat screen, with params
pagepage nameThat page, with params
urla URLOpens the matching native screen when the URL resolves to one, otherwise the app's webview. Goes to the device browser when external is true, or when the value is not an http(s) URL
sharethe messageThe device share sheet
backany non-empty stringGoes back one screen

Anything else is treated as a screen name.

A value is always required. gotoLink returns without doing anything when kind or value is empty, including for back and cart, where the value is otherwise unused.

Three screen values behave specially:

  • default-signin resolves to whichever sign-in screen this app is configured to use, which is the right way to open sign-in from a page. A hard-coded 'signin' is wrong for apps that use a different one.
  • search is ignored unless params.searchQuery is long enough to search for.
  • notifications-inbox opens the push provider's inbox rather than navigating to a screen.

kind: 'product' and kind: 'screen' with value: 'products' reach the same screen. The first is shorter; the second lets you pass extra params.

window.appbrewSDK.gotoLink({ kind: 'product', value: 'blue-tee' })

window.appbrewSDK.gotoLink({
  kind: 'screen',
  value: 'products',
  params: { productHandle: 'blue-tee' },
})

goBackInApp

goBackInApp(): Promise<undefined>

Pops the current screen, returning the shopper to wherever they were before your page.

sendEvent

sendEvent(event: string, data?: Record<string, any>): Promise<undefined>

Forwards an event to every analytics tracker the app has configured. Use one of the platform's own event names to join the app's existing funnel, or your own name for something only your page emits.

window.appbrewSDK.sendEvent('viewed_loyalty_page', { tier: 'gold' })

Failure and timeouts

Nothing here rejects, and the app never sends an error. The three methods that wait resolve with { status: 'error' } five seconds after a call that got no reply. A timeout means one of:

  • The app is older than the action you called. Unknown actions are dropped silently.
  • The page is not rendered by a web-view block, so nothing is listening.
  • The underlying operation failed, and the app reports failure by staying quiet.

Distinguishing them from the page is not possible. See version gates.

Live sample

A page exercising every method is published at solutions.appbrew.tech/web-sdk/appbrew-sdk-sample. Open it inside an app to see real payloads for that app's configuration.

On this page