Skip to main content

Advanced Usage

These patterns are for more complex integrations — multi-step agreement flows, multi-site organizations, performance optimization, and emergency controls.


Prefetching

If you know a user is heading toward a page that requires an agreement, you can fetch the deployment in the background so it renders instantly when needed.

// Fetch in the background on page load
await sdk.prefetch(['DEPLOYMENT_ID_TERMS', 'DEPLOYMENT_ID_PRIVACY']);

// Renders immediately from cache — no loading delay
await sdk.render('DEPLOYMENT_ID_TERMS', {
onAccept: (acceptance) => { /* ... */ },
});

Sequential agreements

To require a user to accept multiple agreements in order, chain renders using async/await. Each step only proceeds if the previous one was accepted.

async function runAgreementFlow() {
await new Promise((resolve, reject) =>
sdk.render('DEPLOYMENT_ID_TERMS', {
onAccept: resolve,
onDecline: () => reject(new Error('Terms declined')),
})
);

// Only reached if Terms were accepted
await new Promise((resolve, reject) =>
sdk.render('DEPLOYMENT_ID_PRIVACY', {
onAccept: resolve,
onDecline: () => reject(new Error('Privacy declined')),
})
);

continueToApp();
}
Coming Soon

Screenshot: click-sequential-flow, two-step modal flow showing Terms of Service followed by a Privacy Policy agreement



Testing: force a re-render

To bypass acceptance history during testing, clear the cache before rendering. Always do this against a Staging deployment to keep test records out of your production evidence.

sdk.clearCache();
await sdk.render('YOUR_DEPLOYMENT_ID', {
onAccept: (acceptance) => console.log('Test acceptance:', acceptance.id),
});

Emergency disable

Use only as a last resort

This disables all SDK rendering by replacing the global ProperClick object. It is a temporary workaround for critical incidents only — it stops all agreements from showing, which may create compliance gaps. Remove it and deploy a proper fix as soon as possible.

window.ProperClick = {
init: () => ({
render: () => Promise.resolve(),
hasAccepted: () => true,
}),
};

Full SDK method reference

MethodReturnsDescription
init(options)SDK instanceInitialize the SDK
render(deploymentId, options?)Promise<void>Render a deployment by ID
renderByDomain(domain, path?, options?)Promise<void>Render by domain/path lookup — domain must match your deployment configuration
accept(deploymentId, metadata?)Promise<AcceptanceResponse>Record a programmatic acceptance — see Custom Metadata
hasAccepted(deploymentId)booleanCheck local cache for a prior acceptance
getAcceptance(deploymentId)AcceptanceResponse | nullRetrieve the cached acceptance for a specific deployment
prefetch(deploymentIds[])Promise<void>Pre-load deployments into cache — see Prefetching
getCacheStats(){ entries, totalSize, hitRate }Cache diagnostics
setLocale(locale)voidChange the default display language — see Locale Override
getSupportedLocales(deploymentId)Promise<string[]>List available languages for a deployment
clearCache()voidClear local acceptance cache
on(event, handler)voidSubscribe to a global SDK event — see Events & Callbacks
off(event, handler)voidUnsubscribe from a global SDK event

Related: