@toughclicks/js-client-sdk
v2.1.1
Published
ToughClicks JS SDK for client integrtions
Downloads
1,292
Readme
📦 Documentation
Our comprehensive documentation is hosted here at https://developers.toughclicks.com.
Getting Help
If you need help using our library, please contact our team via https://developers.toughclicks.com/docs/getting-help
ToughClicks JavaScript SDK
A JavaScript SDK for handling document acceptance and verification with support for multiple packets.
Features
- Multi-Packet Support: Handle multiple packet IDs with individual display options
- Per-Packet Display Options: Configure different display methods, containers, and settings for each packet
- Optional Packets: Mark packets as optional - users don't need to check them for validation
- Document Acceptance: Track user acceptance of documents across multiple packets
- User Verification: Verify user compliance across all packets
- Flexible Rendering: Support for individual, group, and scroll display methods
- Event-Driven: Listen for validation and acceptance events
Installation
npm install @toughclicks/js-client-sdkImporting CSS
The SDK requires CSS to be imported for proper styling. Import it in your application:
// ES Modules / Vite / Webpack
import "@toughclicks/js-client-sdk/toughclicks.css";
// Or use the full path
import "@toughclicks/js-client-sdk/build/toughclicks.css";If you're not using a framework that supports CSS imports in JavaScript, reference the CDN:
<!-- optionally add css -->
<link
rel="stylesheet"
href="https://cdn.toughclicks.com/lib/<version>/toughclicks.css"
/>Basic Usage
Single Packet (Legacy)
import { ToughClicks, TCDisplayMethod } from "toughclicks-js";
const toughClicks = new ToughClicks(
"your-token-here",
"single-packet-id",
true, // debug mode
"production" // environment
);
// Set display options
toughClicks.setDisplayOptions({
containerId: "my-container",
signerIdSelector: "user-id-input",
signerId: null,
displayMethod: TCDisplayMethod.individual,
shouldOpenModal: true,
manualAcceptance: false,
});
// Render the packet
toughClicks.render();Multiple Packets (New)
import { ToughClicks, TCDisplayMethod } from "toughclicks-js";
const toughClicks = new ToughClicks(
"your-token-here",
["packet1-id", "packet2-id", "packet3-id"],
true, // debug mode
"production", // environment
undefined, // getPageContext (default)
[
{
packetId: "packet1-id",
displayOptions: {
containerId: "packet1-container",
signerIdSelector: "user-id-1",
signerId: null,
displayMethod: TCDisplayMethod.individual,
shouldOpenModal: true,
manualAcceptance: false,
},
},
{
packetId: "packet2-id",
displayOptions: {
containerId: "packet2-container",
signerIdSelector: "user-id-2",
signerId: null,
displayMethod: TCDisplayMethod.group,
shouldOpenModal: false,
manualAcceptance: true,
},
},
{
packetId: "packet3-id",
displayOptions: {
containerId: "packet3-container",
signerIdSelector: "user-id-3",
signerId: null,
displayMethod: TCDisplayMethod.scroll,
shouldOpenModal: true,
manualAcceptance: false,
},
},
]
);
// Render all packets
toughClicks.render();Optional Packets
You can mark packets as optional, meaning users don't need to check them for the overall validation to pass. Optional packets will only send API calls if the user actually checks them.
import { ToughClicks, TCDisplayMethod } from "toughclicks-js";
const toughClicks = new ToughClicks(
"your-token-here",
["required-terms", "optional-marketing"],
true, // debug mode
"production", // environment
undefined, // getPageContext (default)
[
{
packetId: "required-terms",
displayOptions: {
containerId: "required-container",
signerIdSelector: "user-id",
signerId: null,
displayMethod: TCDisplayMethod.individual,
shouldOpenModal: false,
manualAcceptance: false,
optional: false, // Required packet (default)
},
},
{
packetId: "optional-marketing",
displayOptions: {
containerId: "optional-container",
signerIdSelector: "user-id",
signerId: null,
displayMethod: TCDisplayMethod.individual,
shouldOpenModal: false,
manualAcceptance: false,
optional: true, // Optional packet
},
},
]
);
// Event listeners
toughClicks.on("tc-valid", (state) => {
// This will fire when all REQUIRED packets are valid
// Optional packets don't affect this validation
console.log("All required packets are valid!");
});
toughClicks.on("tc-accepted", (state) => {
// This will fire when all checked packets are accepted
// Only sends API calls for packets that were actually checked
console.log("Packets accepted!");
});Key Points:
- Optional packets don't affect the
tc-validevent - API calls are only sent for packets that were actually checked
- Users can proceed with only required packets checked
- Optional packets provide opt-in functionality for additional consent
API Reference
Constructor
new ToughClicks(
token: string,
packetIds: string | string[],
debug?: boolean,
environment?: TCEnvironment,
getPageContext?: () => TCContextState,
packetDisplayOptions?: TCPacketDisplayOptions[]
)Methods
Core Methods
render(): Promise<boolean>- Render all packetsaccept(): Promise<boolean>- Accept all packetsverify(userId: string): Promise<TCVerificationResponse[]>- Verify user across all packets
Display Options (Per-Packet)
setPacketDisplayOptions(packetId: string, options: TCDisplayOptions): boolean- Set display options for a specific packetgetPacketDisplayOptions(packetId: string): TCDisplayOptions | null- Get display options for a specific packetsetAllPacketDisplayOptions(packetDisplayOptions: TCPacketDisplayOptions[]): boolean- Set display options for multiple packets
State Management
setCustomData(customData: object): boolean- Set custom data for all packetssetSignerEmailAddress(email: string): boolean- Set signer email for all packetssetDynamicData(dynamicData: object | null): boolean- Set dynamic data for all packets
Utility Methods
setDebug(debug: boolean): boolean- Enable/disable debug modesetTTL(ttl: number): boolean- Set cache TTLclearCache(): boolean- Clear all cached data
Event Handling
on(event: TCEventTypes, callback: Function): void- Register event listener
Events
tc-valid- Emitted when validation state changestc-accepted- Emitted when all packets are acceptedtc-internal-error- Emitted on internal errors
Types
TCDisplayOptions
interface TCDisplayOptions {
containerId?: string;
signerIdSelector: string | null;
signerId: string | null;
displayMethod: TCDisplayMethod | null;
shouldOpenModal: boolean | null;
manualAcceptance: boolean | false;
optional?: boolean; // Mark packet as optional (default: false)
}TCPacketDisplayOptions
interface TCPacketDisplayOptions {
packetId: string;
displayOptions: TCDisplayOptions;
}TCDisplayMethod
enum TCDisplayMethod {
individual = "individual",
group = "group",
scroll = "scroll",
}Display Methods
Individual
Documents are displayed as separate checkboxes, each requiring individual acceptance.
Group
All documents in a packet are grouped into a single checkbox for collective acceptance.
Scroll
Documents are displayed in scrollable containers that must be scrolled to the bottom before acceptance is allowed.
Examples
Mixed Display Methods
const toughClicks = new ToughClicks(
"token",
["terms-packet", "privacy-packet", "consent-packet"],
true,
"production",
undefined,
[
{
packetId: "terms-packet",
displayOptions: {
containerId: "terms-container",
signerIdSelector: "user-id",
displayMethod: TCDisplayMethod.scroll,
shouldOpenModal: true,
manualAcceptance: false,
},
},
{
packetId: "privacy-packet",
displayOptions: {
containerId: "privacy-container",
signerIdSelector: "user-id",
displayMethod: TCDisplayMethod.group,
shouldOpenModal: false,
manualAcceptance: true,
},
},
{
packetId: "consent-packet",
displayOptions: {
containerId: "consent-container",
signerIdSelector: "user-id",
displayMethod: TCDisplayMethod.individual,
shouldOpenModal: true,
manualAcceptance: false,
},
},
]
);Event Handling
toughClicks.on("tc-valid", (state) => {
console.log("All packets valid:", state.allPacketsValid);
if (state.allPacketsValid) {
// Enable submit button
document.getElementById("submit-btn").disabled = false;
}
});
toughClicks.on("tc-accepted", (state) => {
console.log("All packets accepted:", state.allPacketsAccepted);
if (state.allPacketsAccepted) {
// Proceed to next step
window.location.href = "/next-page";
}
});Migration from Single Packet
If you're migrating from the single packet API:
- Constructor: Change from
new ToughClicks(token, packetId, ...)tonew ToughClicks(token, [packetId], ...) - Display Options: Use
setPacketDisplayOptions(packetId, options)instead ofsetDisplayOptions(options) - Verification: The
verify()method now returns an array of results instead of a single result - Events: Event handlers now receive
TCMultiPacketStateinstead ofTCState
License
MIT License - see LICENSE file for details.
