Miniwall Docs
Web SDK

mountPaywall

Draw a screen inline inside an element on your page, like a pricing section, and control it with a handle.

mountPaywall draws a screen inside an element you choose, instead of over the page. Use it for a pricing section, a settings page or any place where 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),
});

// Later, to remove it:
handle.destroy();

Options

mountPaywall takes PaywallOptions: the same options as presentPaywall except the display ones. There is no mode, position, size, duration or closeOnBackdrop, because the screen is part of your layout. A placement's display format and trigger are ignored for inline screens.

OptionTypeWhat it does
paywallPaywallSourceRequired. Placement, paywall ID, URL or JSON.
products, variablesPerPackage, customVariablesPrices and text values. See Purchases and prices.
locale, colorMode, maxContentWidthLanguage, colour scheme and maximum content width.
screensLinked screens for JSON and URL sources.
attributesAttributesVisitor attributes for the placement's audiences.
onPurchase, onRestore, onAction, onAnswer, onClose, onSkip, onOpenUrl, onErrorSee Callbacks.

The handle

interface PaywallHandle {
  destroy(): void;
  answers(): Answers;
  shown: boolean;
  skipReason?: 'frequency_cap' | 'audience' | 'holdout';
}
MemberWhat it does
destroy()Removes the screen and frees its resources. Safe to call more than once.
answers()The answers the visitor has given so far, across every screen of a flow. {} when there are no questions.
shownfalse when the placement's targeting chose to show nothing. Nothing was drawn.
skipReasonWhy nothing was drawn: frequency_cap, audience or holdout.

How it differs from presentPaywall

  • It stays on the page. A purchase, a restore, a button press or a close does not remove the screen. Your callbacks run, and you decide what to do next. Call handle.destroy(), or change your own layout. For a close button press, onClose is called and a close event is recorded, but the screen is still there until you remove it.
  • No promise result. The returned promise resolves once the screen is drawn. Results come from the callbacks (onPurchase, onAction and the others).
  • No focus handling. The SDK does not trap focus or lock scrolling. The screen is a normal part of the page.
  • Skipped placements draw nothing. If targeting skips, the handle has shown: false and onSkip is called. Your container stays empty. Make sure the page still looks right, for example by showing a different section.
  • Screens in a flow (with "Go to another screen" buttons) replace each other inside the container.

Layout

The SDK appends one element, div[data-ui-kit-paywall], to your container and draws inside a shadow root. The element is display: block and as wide as the container. Give the container the width you want. The screen's own width limit comes from its design, and maxContentWidth can narrow it.

Your page's CSS does not reach inside the screen, and the screen's CSS does not leak out.

Errors

The promise rejects if the screen cannot be loaded (wrong key, unknown placement, no network and no saved copy). Purchase and renderer errors go to onError. See Errors.

On this page