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.
Banner clicked
Whether the customer has clicked the reward banner for a specific article.
| Key | cheggout_banner_clicked_<ARTICLE_ID> |
| Type | Boolean |
| Example | cheggout_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).
[
{ "rewardId": 121783, "isSeen": false, "claimed": false },
{ "rewardId": 121782, "isSeen": false, "claimed": false }
]
| Field | Meaning |
|---|---|
rewardId | The card identifier |
isSeen | Whether it has been viewed or scratched |
claimed | Whether 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:
| Measure | How |
|---|---|
| Trigger calls made | Count your own bannerTriggerEvent calls |
| Milestones reached | Your own scroll or read tracking |
| Login redirects for a claim | Your own login flow |
| Successful re-triggers after login | Count them in your return handler |
| Banner clicks | Read 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.