Skip to main content

Events Reference

Complete reference for all events emitted by the SDK.


Event map

interface SDKEventMap {
ready: { state: SDKState };
'auth:login': { user: User };
'auth:logout': {};
'paywall:shown': {};
'paywall:hidden': {};
'article:purchased': { creditsSpent: number; remainingBalance: number };
'credits:insufficient': { required: number; available: number };
'comment:posted': { comment: Comment };
'comment:liked': { commentId: string; hasLiked: boolean };
'comment:deleted': { commentId: string };
error: { message: string; error?: unknown };
}

ready

When: SDK has finished initialising — access check is complete, all UI is rendered.

cc.on('ready', ({ state }) => {
// state: SDKState
});
Payload fieldTypeDescription
stateSDKStateComplete SDK state snapshot

auth:login

When: Reader successfully authenticates (popup or redirect flow).

cc.on('auth:login', ({ user }) => {
// user: User
});
Payload fieldTypeDescription
user._idstringUnique reader ID
user.firstNamestringFirst name
user.lastNamestringLast name
user.emailstringEmail address
user.creditsnumberCurrent credit balance

auth:logout

When: Reader's session ends — token expired or the API returned 401.

cc.on('auth:logout', () => { ... });

No payload.


paywall:shown

When: The paywall overlay appears (reader does not have access).

cc.on('paywall:shown', () => { ... });

No payload.


paywall:hidden

When: The paywall overlay is dismissed and content is revealed. This fires both when a reader already has access (on page load) and when they just purchased.

cc.on('paywall:hidden', () => { ... });

No payload.


article:purchased

When: Reader successfully purchases the current article.

cc.on('article:purchased', ({ creditsSpent, remainingBalance }) => {
// ...
});
Payload fieldTypeDescription
creditsSpentnumberCredits deducted for this article
remainingBalancenumberReader's remaining credit balance

credits:insufficient

When: Reader tries to buy but their credit balance is too low.

cc.on('credits:insufficient', ({ required, available }) => {
// The SDK shows a "Top up" button automatically
});
Payload fieldTypeDescription
requirednumberCredits needed for this article
availablenumberReader's current balance

comment:posted

When: Reader successfully posts a new comment.

cc.on('comment:posted', ({ comment }) => {
// comment: Comment
});
Payload fieldTypeDescription
comment._idstringNew comment ID
comment.contentstringComment text
comment.authorCommentAuthorAuthor name/id
comment.createdAtstringISO timestamp

comment:liked

When: Reader likes or unlikes a comment.

cc.on('comment:liked', ({ commentId, hasLiked }) => { ... });
Payload fieldTypeDescription
commentIdstringID of the comment
hasLikedbooleantrue if just liked, false if just unliked

comment:deleted

When: Reader deletes one of their comments.

cc.on('comment:deleted', ({ commentId }) => { ... });
Payload fieldTypeDescription
commentIdstringID of the deleted comment

error

When: The SDK encounters an error — network failure, API error, or unexpected exception.

cc.on('error', ({ message, error }) => {
console.error(message, error);
Sentry.captureException(error);
});
Payload fieldTypeDescription
messagestringHuman-readable error description
errorunknownThe underlying error object (if any)

Native CustomEvents

All SDK events are also dispatched as native CustomEvents on document, prefixed with contentcredits::

// Same as cc.on('auth:login', handler)
document.addEventListener('contentcredits:auth:login', (e) => {
console.log(e.detail); // { user: { ... } }
});

// Useful for Google Tag Manager
document.addEventListener('contentcredits:article:purchased', (e) => {
dataLayer.push({ event: 'cc_purchase', ...e.detail });
});