JS <--> Native Bridge
Use the JS <--> Native Bridge to call OnsideKit from JavaScript running inside a WKWebView. This integration fits apps built as a web wrapper, where most product logic lives in a website but the app still needs native OnsideKit features such as in-app purchases, attribution, and event tracking.
The bridge is only a transport layer between JavaScript and native code. It does not add new capabilities and does not change the semantics, lifecycle, or error handling of existing OnsideKit APIs. The behavior described in Installation Guide, User account, Attribution, Building funnels with event tracking, and Purchasing & Restoring Purchases still applies. This page focuses on WKWebView configuration and the JavaScript API exposed by the bridge.
Initialize OnsideKit first
Start with the same OnsideKit setup used for a native integration.
Complete the installation, callback URL scheme setup, and SDK initialization exactly as described in Installation Guide.
The only difference is delegate and observer setup.
If you plan to use OnsideKit from JavaScript, do not assign OnsideKit delegates or transaction observers in native code. During WKWebView configuration, OnsideJS registers itself implicitly as the required delegate and observer layer.
Configure WKWebView
After OnsideKit is installed and initialized, configure your WKWebView by passing its instance to OnsideJS.configureOnsideForWebView(_:).
This is the only required WKWebView setup step.
import WebKit
import OnsideKit
let webView = WKWebView(frame: .zero)
OnsideJS.configureOnsideForWebView(webView)Load your web content
After configuration, use the WKWebView as usual and load your web content in the normal way.
If configuration succeeds, JavaScript running inside the page gets access to window.onside.
Before you call any bridge method, initialize the JS API version your code supports.
Call window.onside.initializeOnside('v1') once during your JS bootstrap.
'v1' declares that your client code supports JS Bridge API v1. This is currently the only supported version.
Call window.onside.initializeOnside('v1') before any other window.onside method or callback.
After initialization, you can call methods and assign callbacks on window.onside.
Conventions
Setters and "fire-and-forget" methods (
setAppearance,setShouldForceLocalLoginMethods,setDefaultCountryCodeAssumption,logout,trackEvent) return synchronously and never throw.Everything else returns a
Promise. Resolves with the success payload, rejects with a typed error envelope.Error envelope shape. All native
enum: Errorcases without associated values arrive as{ <caseName>: {} }. Discriminate with'caseName' in error, or pattern-match against the union types inonside.d.ts.
API Reference — v1
This reference describes JS Bridge API version v1.
Configuration
initializeOnside('v1')
Initialize the JS bridge API. Call this once before any other window.onside method or callback.
The argument declares the API version your JS client supports. Currently only 'v1' is supported.
setAppearance(theme)
Override the theme used for native UI presented from JS (login, payment methods, etc.). 'system' follows the OS-level appearance.
setShouldForceLocalLoginMethods(force)
When true, the login screen exposes only local login methods (SMS / e-mail) and hides federated providers. Useful for environments where federated login is not desired.
setDefaultCountryCodeAssumption(countryCode)
Default country code assumed when the system region is unknown. Pass an empty string to clear the assumption.
Analytics
trackEvent(input)
Send a single analytics event. name may be a predefined Onside event (e.g. purchaseCompleted, subscriptionStarted) or any custom identifier. Validation is enforced natively:
name and parameter keys must match
^[a-zA-Z][a-zA-Z0-9_]*$and be ≤ 40 chars (longer names are truncated; reserved prefixesonside_and$$are rejected);at most 25 effective parameters per event;
string values longer than 100 chars are truncated.
Auth
requestLogin()
Show the login flow. Resolves on successful authentication. Rejects with OnsideLoginError.
logout()
Log out the current user.
UI
presentPaymentMethodsManager()
Show the payment-methods management screen. Triggers a login flow first if the user is not authenticated. Rejects with OnsidePaymentMethodsManagerError.
Storefront
getCurrentStorefront()
Currently selected storefront, or null if none is selected yet. The selection can change at any time — subscribe to onStorefrontChanged for updates.
Products
loadProducts(input)
Load products by identifiers. The response contains:
products— products that resolved successfully;invalidProductIdentifiers— identifiers that did not resolve (unknown, malformed, etc.).
Returned products are also cached natively so that purchase can look them up by productIdentifier.
Rejects with OnsideProductsRequestError.
Payments
purchase(input)
Initiate a purchase. The product identifier must refer to a product previously returned by loadProducts; otherwise the promise rejects with { unknownProduct: {} }.
The promise itself only reports the pre-flight outcome (login outcome, lookup, etc.). Subsequent transaction state changes are delivered via onTransactionsUpdated; JS is responsible for calling finishTransaction once a transaction reaches a terminal state.
Rejects with JSPurchaseError.
restoreCompletedTransactions()
Restore previously completed transactions. The promise only reports the pre-flight outcome (e.g. loginDiscarded). The completion of the restore flow itself is delivered via onRestoreCompletedTransactionsFinished or onRestoreCompletedTransactionsFailedWithError. Restored transactions arrive through onTransactionsUpdated.
Rejects with OnsidePaymentQueueRequestRestoreError.
getTransactions()
Snapshot of currently alive transactions in the payment queue. Useful on page reload to rebuild UI state without waiting for the next event.
finishTransaction(id)
Finish a transaction by its opaque id (the id field of JSPaymentTransaction). Removes the transaction from the queue — onTransactionsRemoved will fire.
Rejects with JSFinishTransactionError.
Attribution
getAttributionMetadata()
Fetch attribution metadata for the current install/user (e.g. the referer URL that brought the user to the install).
Rejects with OnsideAttributionMetadataError.
History
getSignedInAppsHistory()
Fetch the signed in-apps history JWT for the current user. The response carries both the raw bytes (base64-encoded) and a UTF-8 representation, when applicable.
Rejects with OnsideSignedInAppsHistoryRequestError.
Native → JS Callbacks
Assign a function to the corresponding property on window.onside to start receiving the event. All callbacks are optional; a missing handler is a no-op (with one exception, see shouldContinueTransaction).
onTransactionsUpdated(transactions)
Transactions added to the queue or transitioned to a new state. Inspect transactionState and react accordingly. Once the state reaches purchased, restored or failed, JS must call finishTransaction to remove it from the queue.
onTransactionsRemoved(transactions)
Transactions that have been removed from the queue (typically after finishTransaction).
onStorefrontChanged(storefront)
Storefront selection changed; null means the storefront is no longer available.
onRestoreCompletedTransactionsFinished()
The restoreCompletedTransactions flow finished successfully.
onRestoreCompletedTransactionsFailedWithError(error)
The restoreCompletedTransactions flow failed.
shouldContinueTransaction(input)
Async pre-flight gate the queue invokes before processing a transaction in a particular storefront. Return false to cancel. If no handler is registered, native defaults to true.
Domain Types
JSPrice
Numeric monetary value with an ISO-4217 currency code (e.g. "EUR").
JSPeriod
Subscription/discount period — analogous to StoreKit's SKProductSubscriptionPeriod.
JSPricePeriod
A price valid for the given period (introductory price, discounted price, etc.).
JSProduct
A product as returned by loadProducts. subscriptionGroupIdentifier and subscriptionPeriod are present only for subscriptions.
JSStorefront
The selected storefront — opaque storefront id plus its ISO-3166 countryCode.
JSPayment
The payment that produced a transaction, embedded inside JSPaymentTransaction.payment. appAccountToken is the optional opaque token passed to purchase.
JSPaymentTransactionState
Lifecycle states of a transaction:
purchasing
Still in flight: created, awaiting payment, etc.
purchased
Completed successfully. Call finishTransaction(id).
restored
Returned by restoreCompletedTransactions. Call finishTransaction(id).
failed
Final, failed. error is populated. Call finishTransaction(id) to remove.
JSPaymentTransaction
id— opaque UUID string. The only stable handle for this transaction; pass it tofinishTransaction.transactionIdentifier— server-side transaction id (may be absent inpurchasing).originalTransactionIdentifier— id of the original transaction for restored/renewed cases.error— populated only forfailedtransactions.
JSAttributionMetadata
Currently exposes only the referer URL. May be extended in the future.
JSSignedInAppsHistory
dataBase64— raw payload bytes, base64-encoded.string— UTF-8 decoded payload, when applicable (the payload is typically a JWT and decodes to a printable string).
JSProductsResponse
Result of loadProducts.
JSEventParameterValue
Value type for trackEvent parameters: a primitive or an array of primitives. Array elements (JSEventArrayParameterValue) follow the same primitive set without further nesting.
Errors
All native enum: Error cases without associated values arrive on the JS side as { <caseName>: {} }. The bridge also defines a few JS-specific error types listed at the end.
OnsideLoginError
loginDiscarded
The user dismissed/cancelled the login flow.
OnsideProductsRequestError
cancelled
The request was cancelled.
connectionError
Network connectivity error.
appNotRegistered
The current app is not registered with Onside.
invalidProductIdentifier
Server rejected the product identifier(s).
serviceUnavailable
Server returned a 5xx.
internalError
Other unexpected error.
OnsideSignedInAppsHistoryRequestError
notLoggedIn
Operation requires an authenticated user.
notSupportedInLocalTesting
Not supported when running with a local-testing storefront.
cancelled
The request was cancelled.
connectionError
Network connectivity error.
appNotRegistered
The current app is not registered with Onside.
serviceUnavailable
Server returned a 5xx.
internalError
Other unexpected error.
OnsidePaymentMethodsManagerError
loginDiscarded
The user dismissed the implicit login flow.
notSupportedInLocalTesting
Not supported when running with a local-testing storefront.
OnsidePaymentQueueRequestRestoreError
loginDiscarded
The user dismissed the implicit login flow.
OnsideTransactionsRestoreError
cancelled
The restore was cancelled.
connectionError
Network connectivity error.
appNotRegistered
The current app is not registered with Onside.
serviceUnavailable
Server returned a 5xx.
internalError
Other unexpected error.
OnsidePaymentTransactionError
Populated on JSPaymentTransaction.error for failed transactions.
cancelled
The transaction was cancelled.
OnsideAttributionMetadataError
connectionError
Network connectivity error.
appNotRegistered
The current app is not registered with Onside.
serviceUnavailable
Server returned a 5xx.
internalError
Other unexpected error.
JSPurchaseError
JS-bridge specific error for purchase.
unknownProduct
The productIdentifier is not in the local cache. Call loadProducts first.
loginDiscarded
The user dismissed the implicit login flow.
JSFinishTransactionError
JS-bridge specific error for finishTransaction.
unknownTransaction
No transaction with the given id exists in the queue.
Reference
The full machine-readable contract is available in onside.d.ts.
Last updated
Was this helpful?