Tracking subscription state
Read and react to a user's subscription status and entitlements.
Beta
The Web SDK is in beta and its API may change between releases.
Subscription status
sw.subscriptionStatus is a reactive value with three shapes:
type SubscriptionStatus =
| { status: "UNKNOWN" }
| { status: "INACTIVE" }
| { status: "ACTIVE"; entitlements: Entitlement[] };const status = sw.subscriptionStatus.value;
if (status.status === "ACTIVE") {
console.log("entitled to:", status.entitlements.map((e) => e.id));
}UNKNOWN means the SDK has not resolved status yet. Do not treat it as INACTIVE.
Reacting to changes
Subscribe to the signal, or listen for the event.
const unsubscribe = sw.subscriptionStatus.subscribe((status) => {
render(status);
});const ac = new AbortController();
sw.events.addEventListener(
"subscriptionStatus_didChange",
() => render(sw.subscriptionStatus.value),
{ signal: ac.signal },
);
// later
ac.abort();Subscribing fires the callback synchronously once with the current value before it returns, so you do not need a separate initial read to prime your UI.
Customer info
sw.customerInfo carries the fuller picture of the customer, or null until the first entitlements read lands. There is a snapshot method too, and a way to force a refresh:
sw.customerInfo.value;
await sw.purchases.getCustomerInfo();
await sw.purchases.refreshCustomerInfo();Restoring
await sw.purchases.restore();Setting status yourself
If you run your own checkout instead of Superwall's, push the resulting status in:
sw.purchases.setSubscriptionStatus({
status: "ACTIVE",
entitlements: [
{ id: "pro", type: "SERVICE_LEVEL", isActive: true, productIds: [] },
],
});An Entitlement needs all four of id, type, isActive, and productIds. Note that
@superwall/verify defines a different type also called Entitlement, whose field is
identifier rather than id. The two are not interchangeable.
Setting a status equivalent to the current one is a no-op: no event fires and the delegate is not called.
See Purchases for the full picture on custom checkout.
Entitlements tokens
For server-side checks, the SDK exposes a Superwall-signed token describing the user's entitlements.
sw.entitlementsToken.value; // reactive, null until issued
sw.purchases.getEntitlementsToken(); // snapshotForward it to your backend and verify it with @superwall/verify. A valid signature proves Superwall issued those entitlements, with no round trip per request. See Server-side gating.
The token is best-effort and will be null when the backend is not issuing one. It refreshes on
roughly a ten-minute poll while the tab is in the foreground, and eagerly after checkout, after a
restore, on identify with a different user, and on reset.
How is this guide?