loadPaywall
Fetch a screen's JSON without showing it, and learn how sources, caching, timeouts and the offline copy work.
loadPaywall resolves a screen source to its JSON and returns it. It draws nothing and sends no analytics events. Use it to read what a screen needs before you show it, for example to list its package IDs and fetch prices for them.
function loadPaywall(source: PaywallSource, init?: RequestInit): Promise<PaywallJson>;import { configure, loadPaywall, getPackageIds } from '@ui-kit/web';
configure({ apiKey: 'pk_...' });
const paywall = await loadPaywall({ placement: 'upgrade_button' });
const ids = getPackageIds(paywall); // for example ['monthly', 'annual']
const products = await fetchPricesFor(ids); // your own code| Parameter | Type | What it does |
|---|---|---|
source | PaywallSource | Where to get the screen. See below. |
init | RequestInit | Extra options for fetch, used only when source is a URL string. |
Sources
type PaywallSource = { placement: string } | { paywallId: string } | PaywallJson | string;| Source | Loads | Analytics |
|---|---|---|
{ placement: 'key' } | The screen the placement shows now. A schedule in force is applied by the server. For an A/B test, the visitor's side is picked. Audiences, the frequency limit and the holdout are not applied by loadPaywall. Recommended. Needs configure({ apiKey }). | Yes (when shown with presentPaywall or mountPaywall) |
{ paywallId: 'id' } | That screen's published version. Needs configure({ apiKey }). | Yes |
'https://.../paywall.json' | JSON from any URL, such as a file you downloaded from the dashboard and host yourself. | None |
| a JSON object | That JSON as it is. | None |
A JSON object or URL must have the screen format: default_locale, components_config.base and components_localizations. If components_config.base is missing the call fails with Not a paywall JSON: expected components_config.base. A wrapper object with a paywallData field is unwrapped for you. A missing components_localizations becomes an empty object.
Download a screen's JSON from the dashboard with Download JSON on the Screens page. Because a downloaded file is a copy, it does not change when you publish. A placement does.
Caching and the offline copy
For a placement or a paywall ID the SDK keeps its own copy of the last answer:
- It sends the request with the last
ETagit saw, so an unchanged screen costs a short304answer. - The copy is kept in memory and in
localStorageunderuikit:v1:plus the request URL. - The browser's own HTTP cache is skipped, so a new publish shows on the next load. The Miniwall CDN caches an answer for about 30 seconds, so a publish reaches your site within about a minute.
- If the network fails, the request times out, or the server answers with a 5xx error, the last copy is used. A published screen keeps working offline.
- A 4xx answer (a wrong key, an unknown placement, a domain that is not allowed) is an error, even if there is a copy.
timeoutMs (default 8000 ms, set in configure) is how long to wait. After that the saved copy is used. With no copy the call rejects with UIKit: the paywall took too long to load.
A URL source is fetched with fetch(url, { headers: { accept: 'application/json' }, ...init }). It is not cached by the SDK and has no timeout of its own. It fails with Could not load paywall (STATUS) from URL on a non-2xx answer.
The delivery response
For reference, the SDK calls GET {apiUrl}/v1/sdk/placements/KEY?key=pk_...&v=2 (or /v1/sdk/paywalls/ID). The answer contains the published screen and everything the browser needs to decide what to show:
| Field | What it is |
|---|---|
placement, paywallId, version | Which placement, screen and published version. |
paywall | The screen JSON. |
packages | The package IDs your site must price. |
experiment | A running A/B test: its id, shareB and side B's full delivery. null when none. |
rules | The audiences in order: id, conditions and the screen to show, or null for nothing. |
frequency | The frequency limit, or null. |
holdout | The holdout id and share, or null. |
display, trigger | The placement's format and trigger. |
Audiences, the frequency limit and the holdout ship as rules and are decided in the browser, so your visitors' attributes never leave the page. See Targeting attributes.
Related
- presentPaywall
- Purchases and prices (
getPackageIds) - Errors
- Events and privacy