Skip to main content

Interaction data

The widget records what the customer has done in browser localStorage. You can read it to track reward-related actions and — most usefully — to avoid triggering the same banner twice for the same article.

This is optional. Use it if you want that behaviour; ignore it otherwise.

Whether the customer has clicked the reward banner for a specific article.

Keycheggout_banner_clicked_<ARTICLE_ID>
TypeBoolean
Examplecheggout_banner_clicked_12345 = true

true means the customer has already clicked the reward banner for that article.

const articleId = getCurrentArticleId();
const alreadyClicked =
localStorage.getItem(`cheggout_banner_clicked_${articleId}`) === 'true';

if (!alreadyClicked) {
window.CheggoutRewards.bannerTriggerEvent(virtualId, authToken, 'article_read', 'web', {});
}

This is the main reason to read this data at all — re-showing a banner the customer already engaged with is the most visible way a widget integration feels broken.

Card opened and claimed

The status of the customer's scratch card rewards, tracking whether each card has been viewed or scratched (isSeen) and whether the reward has been claimed (claimed).

Sample value
[
{ "rewardId": 121783, "isSeen": false, "claimed": false },
{ "rewardId": 121782, "isSeen": false, "claimed": false }
]
FieldMeaning
rewardIdThe card identifier
isSeenWhether it has been viewed or scratched
claimedWhether the reward has been claimed

Useful for showing an unclaimed-reward indicator elsewhere on your site:

const KEY = 'REPLACE_STORAGE_KEY'; // TBD — confirm the exact key with Cheggout

function unclaimedRewardCount() {
try {
const raw = localStorage.getItem(KEY);
if (!raw) return 0;
const cards = JSON.parse(raw);
return cards.filter(c => !c.claimed).length;
} catch {
return 0;
}
}

TBD The exact storage key for this value is not published — only its shape and purpose. Read defensively, and treat an absent or unparseable value as "no data" rather than as an error.

Working with browser storage safely

Wrap every read in a try/catch. Storage can be disabled, full, or blocked by privacy settings. Your page must work when it is unavailable.

Treat it as a hint, not as truth. It is per-browser and per-device. A customer on a second device has none of it, and clearing site data resets it. The authoritative reward state lives with Cheggout.

Do not write to these keys. They belong to the widget. Writing your own values into them risks breaking the widget's behaviour in a future build.

Expect it to grow. One key per article accumulates over time. If your site has heavy repeat readers, consider periodically pruning your own keys — but leave the widget's alone.

No callback API

TBD There is no documented JavaScript callback, event emitter or promise for banner clicks, card opens or claims. Browser storage is the documented mechanism for observing what happened.

That has real consequences for how you integrate:

  • You cannot react synchronously to a claim — you can only observe the state afterwards.
  • Server-side analytics of widget interactions must come from your own instrumentation around the trigger calls, not from the widget.
  • Polling storage is the only way to notice a change during a page session, and it is a poor substitute for an event.

A formal callback API is on Open items. If your integration needs one, say so — it strengthens the case.

What you can instrument yourself

Even without callbacks, you can measure the parts you control:

MeasureHow
Trigger calls madeCount your own bannerTriggerEvent calls
Milestones reachedYour own scroll or read tracking
Login redirects for a claimYour own login flow
Successful re-triggers after loginCount them in your return handler
Banner clicksRead the storage flag on the next page view

The gap between "milestones reached" and "successful re-triggers after login" is the most valuable number here — it tells you how many customers you are losing in the guest-to-signed-in handoff.

Next