State Reference
The SDK maintains internal state that you can read at any time via cc.getState().
SDKState interface
interface SDKState {
isLoading: boolean;
isExtensionAvailable: boolean;
isLoggedIn: boolean;
hasAccess: boolean;
isLoaded: boolean;
user: User | null;
creditBalance: number | null;
requiredCredits: number | null;
}
Fields
isLoading · boolean
true while the SDK is actively checking access or processing a purchase. Use this to show a loading state in your own UI.
isLoaded · boolean
true once the SDK has finished its initial startup sequence (access check complete). This corresponds to when the ready event fires.
isLoggedIn · boolean
true if the reader has a valid auth token. Equivalent to calling cc.isLoggedIn().
hasAccess · boolean
true if the reader has purchased or been granted access to the current article. When this is true, the premium content is visible and the paywall overlay is hidden.
isExtensionAvailable · boolean
true if the Content Credits Chrome extension was detected in the reader's browser. When the extension is available, the SDK uses it for faster access checking and authentication.
user · User | null
The authenticated reader's profile, or null if not logged in.
interface User {
_id: string;
firstName: string;
lastName: string;
email: string;
credits: number;
roles: ('consumer' | 'publisher' | 'admin')[];
isVerified: boolean;
isActive: boolean;
purchaseHistory: PurchaseItem[];
}
creditBalance · number | null
The reader's current credit balance, or null if not known (reader not logged in, or balance not yet fetched).
requiredCredits · number | null
The number of credits required to unlock the current article, or null if not yet known.
Reading state
Option A — onStateChange config callback
Pass onStateChange in your init() config to receive state on every change. This is the simplest approach for headless mode.
ContentCredits.init({
apiKey: 'pub_YOUR_KEY',
headless: true,
onStateChange: (state) => {
document.getElementById('spinner').hidden = !state.isLoading;
document.getElementById('content').hidden = !state.hasAccess;
},
});
Option B — cc.subscribe(fn)
Call subscribe() on the returned instance. Useful when you can't pass callbacks at init time (e.g. inside a React useEffect).
const cc = ContentCredits.init({ apiKey: 'pub_YOUR_KEY', headless: true });
const unsubscribe = cc.subscribe((state) => {
renderPaywall(state);
});
// Later:
unsubscribe();
Option C — cc.getState() snapshot
Use getState() to read the current state at a specific moment — for example, inside an event handler.
cc.on('ready', () => {
const state = cc.getState();
console.log('Access:', state.hasAccess);
console.log('User:', state.user?.firstName);
});
cc.on('auth:login', () => {
const state = cc.getState();
updateHeader(state.user);
});
getState() returns a snapshot; it does not subscribe to future changes.
Initial state (before ready fires)
Before the ready event, all fields are in their default/unknown state:
{
"isLoading": false,
"isLoaded": false,
"isLoggedIn": false,
"hasAccess": false,
"isExtensionAvailable": false,
"user": null,
"creditBalance": null,
"requiredCredits": null
}