Embed a screen
Draw a screen inline inside your own layout, like a pricing section or an onboarding step.
Embedding draws a screen inside your own layout instead of over the page or app. Use it for a pricing section, an onboarding step, a settings page or anywhere the screen is part of the layout.
function mountPaywall(container: HTMLElement, options: PaywallOptions): Promise<PaywallHandle>;import { configure, mountPaywall } from '@ui-kit/web';
configure({ apiKey: 'pk_...' });
const handle = await mountPaywall(document.querySelector('#pricing'), {
paywall: { placement: 'pricing' },
products: { annual: { price: 59.99, currency: 'USD', period: 'year' } },
onPurchase: async ({ packageId }) => startCheckout(packageId),
});
handle.destroy(); // later, to remove itThe same thing exists as a tag (Web component) and as a component (React).
Options
Embedding takes the same options as Present a screen except the display ones (no mode, style, position, size, duration or closeOnBackdrop): the screen is part of your layout. A placement's display format and trigger are ignored.
| Option | What it does |
|---|---|
| Source | Required. Placement, paywall ID, JSON (web also URL). |
products, variablesPerPackage, customVariables, locale, colorMode, screens, attributes | As in Present a screen. Web also takes maxContentWidth. |
| Callbacks | onPurchase, onRestore, onAction, onAnswer, onOpenUrl, onError (web also onClose, onSkip). See Callbacks. |
onFinish | iOS and Android only: called once with the result when the screen ends (purchased, restored, closed, action or skipped). |
The handle (web)
mountPaywall returns a handle once the screen is drawn.
| Member | What it does |
|---|---|
destroy() | Removes the screen and frees its resources. Safe to call more than once. |
answers() | The answers given so far, across every screen of a flow. {} when there are no questions. |
shown | false when targeting chose to show nothing. Nothing was drawn. |
skipReason | frequency_cap, audience or holdout. |
How it differs from present
- It stays in your layout. A purchase, restore, button press or close does not remove the screen. Your callbacks run (web) or
onFinishruns (mobile), and you decide what to do next: callhandle.destroy()or change your own layout. - No result. On web the promise resolves once the screen is drawn; results come from the callbacks. On mobile results come from
onFinish. - Skipped placements draw nothing. The container stays empty (
shown: falseandonSkipon web,onFinishwithskippedon mobile). Make sure your layout still looks right. - Load failures. On web the promise rejects (wrong key, unknown placement, no network and no saved copy; see Errors). On mobile the view stays empty and
onErroris called. - Flows ("Go to another screen" buttons) replace each other inside the container.
- No overlay behaviour. No focus trap, no scroll lock, no sheet or cover. The screen is as wide as the space you give it; give the container the width you want.
On web the SDK appends one div[data-ui-kit-paywall] to your container (display: block, as wide as the container) and draws inside a shadow root. maxContentWidth can narrow it.