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
| Parameter | Type | Required | Description |
|---|
options.receipt | { amount: string; purpose?: string } | No | Per-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'). |
placementOptions | PlacementOptions | No | Per-presentation UI overrides. Full field contract in placement(); post-purchase usage in the Thank-You Layout guide. |
placementId | string | No | Placement 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.
status | When | Next step |
|---|
claimed | User claimed an offer | Deferred: run your conversion, then redeem() — no handle needed. Immediate: nothing — the advertiser tab is already open; render your own confirmation if you want one |
dismissed | User closed the modal, clicked outside, or declined the last offer — or the flow failed (reason.type === 'error') | Respect the decline; reason says which |
unavailable | No eligible offers — or the user is in a measurement control cohort | Show 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;
}
// 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).