Skip to main content
Presents the offer carousel and resolves when the user claims an offer, dismisses the carousel, or no offers are eligible. show() is phase 1 of the two-phase flow — pair it with redeem() in deferred mode.

When to use this

Call show() at the moment you want to present an offer — a cancel flow, a paywall, an onboarding step. What it does on claim depends on redemptionMode:
  • deferred (default): records a transaction and resolves claimed with no redirect — call redeem() later.
  • immediate: also opens the advertiser in a new tab (inside the claim gesture), then resolves the same claimed.
In both modes the SDK renders nothing after a claim — there is no built-in success or confirmation screen. The host owns the post-claim moment: render your own confirmation (or none), keyed off the result. Most integrations present via the fluent placement(id).show() builder, which resolves the same ShowResult; Encore.show() is the inline one-call variant.

Signature

function show(
  options?: {
    receipt?: { amount: string; purpose?: string };  // 'thankYou' layout only — rendered as the status subtitle
  },
  placementOptions?: PlacementOptions,  // per-presentation UI: layout, appearance, header, offerContext, footer
  placementId?: string                  // recorded on the transaction for placement-scoped redeem()
): Promise<ShowResult>
placementOptions and placementId mirror the fluent placement(id, options).show() form — the placement id is recorded the same way.

Parameters

ParameterTypeRequiredDescription
options.receipt{ amount: string; purpose?: string }NoPer-transaction payment context, rendered as the status subtitle under the thankYou layout. Render-only — never sent to Encore’s servers. Pass amount pre-formatted ('$9.99').
placementOptionsPlacementOptionsNoPer-presentation UI overrides. Full field contract in placement(); post-purchase usage in the Thank-You Layout guide.
placementIdstringNoPlacement key recorded on the transaction, so a later placement(id).redeem() resolves this exact claim.

ShowResult

type ShowResult =
  | { status: 'claimed' }                                // user claimed an offer (both modes)
  | { status: 'dismissed';  reason?: NotGrantedReason }  // user closed/declined — or an internal error
  | { status: 'unavailable' };                           // no eligible offers (or a control-cohort ghost trigger)
The result is bare — no transaction handle, no reward copy. claimed is identical in both redemption modes; the only difference is a side effect: in immediate mode the advertiser tab was also opened before show() resolved.
statusWhenNext step
claimedUser claimed an offerDeferred: run your conversion, then redeem() — no handle needed. Immediate: nothing — the advertiser tab is already open; render your own confirmation if you want one
dismissedUser closed the modal, clicked outside, or declined the last offer — or the flow failed (reason.type === 'error')Respect the decline; reason says which
unavailableNo eligible offers — or the user is in a measurement control cohortShow your fallback; do not assume which
reason (a NotGrantedReason) is one of 'userClosedModal', 'userClickedOutside', 'userDeclinedLastOffer', 'noOffersAvailable', or { type: 'error', error }.
show() never rejects. There is no crash path and no try/catch needed: any failure (SDK not configured, network error, unexpected exception) resolves as { status: 'dismissed', reason: { type: 'error', error } }.
The result makes no conversion claim. claimed means the user accepted an offer — the advertiser conversion happens later, asynchronously, via server-side postbacks. Verify conversions and entitlements server-side, by user, with Encore’s Encore’s server-side verification — never from the client, and never from this result.
Deferred hosts never need to track pending state themselves (even across a reload): call redeem() when your flow is ready — the SDK resolves the pending transaction internally, and if nothing is pending it resolves { status: 'none' }.

Examples

Deferred (default)

import Encore from '@encorekit/web-sdk';

const result = await Encore.show();

switch (result.status) {
  case 'claimed':
    // No redirect yet. Run your own conversion, then call Encore.redeem() —
    // the SDK resolves the pending transaction internally; no handle needed.
    break;
  case 'dismissed':
    // result.reason === 'userClosedModal' | 'userDeclinedLastOffer' | { type: 'error', ... }
    break;
  case 'unavailable':
    showFallback();
    break;
}

Immediate

// Configured with redemptionMode: 'immediate'
const result = await Encore.show();
if (result.status === 'claimed') {
  // Advertiser tab already opened inside the claim gesture. The SDK renders
  // nothing after the claim — show your own confirmation here if you want one.
}

Gotchas

  • unavailable is overloaded. It means “no eligible offers” and “measurement control cohort (ghost trigger)” — the SDK keeps them indistinguishable on purpose so incrementality experiments aren’t contaminated. Don’t branch app behavior on a suspected control assignment; just show your normal fallback.
  • Claim ≠ redirect in deferred mode. claimed only records a transaction. The redirect is in redeem().
  • Nothing renders after a claim. The SDK has no built-in success screen — if your flow needs a confirmation moment, render it yourself when the result is claimed.
  • Claim ≠ conversion. Never grant access off a claimed result — verify entitlements server-side, by user (see the warning above).