Configuration
All widget configuration options and member data
This reference covers all configuration options available when initializing the useLoyalty Widget.
Configuration Object
interface UseLoyaltyWidgetConfig {
// Required - Authentication
publicKey: string;
externalId: string;
timestamp: number;
signature: string;
// Optional - API
apiUrl?: string;
// Optional - Appearance
theme?: WidgetTheme;
language?: WidgetLanguage;
// Optional - Member Data
member?: MemberData;
// Optional - Callbacks
onReady?: () => void;
onError?: (error: Error) => void;
onWelcomeBonus?: (points: number) => void;
}Required Parameters
publicKey
Your project's public API key (starts with pk_).
publicKey: "pk_live_abc123xyz";externalId
The unique identifier for the member in your system.
externalId: "user_12345"; // Your user ID
externalId: "cust_abc123"; // Or customer ID
externalId: user.id; // Dynamic valuetimestamp
Current Unix timestamp in milliseconds. Used for replay attack prevention.
timestamp: Date.now(); // Current time
timestamp: 1704067200000; // Specific timestampTimestamps older than 5 minutes are rejected. Always generate fresh timestamps.
signature
HMAC-SHA256 signature generated server-side.
signature: "a1b2c3d4e5f6..."; // 64-character hex stringOptional Parameters
apiUrl
Override the default API URL (useful for self-hosted instances).
apiUrl: "https://app.useloyalty.app"; // Default
apiUrl: "https://your-instance.com/api"; // Self-hostedtheme
Customize the widget appearance. See Theming for full details.
theme: {
primaryColor: '#6366f1',
backgroundColor: '#ffffff',
textColor: '#1e293b',
position: 'right'
}language
Set the widget language. See Internationalization for details.
language: "en"; // English (default)
language: "es"; // Spanish
language: "fr"; // French
language: "de"; // German
language: "ja"; // Japanese
language: "zh-CN"; // Chinese (Simplified)member
Provide member data to sync with the widget:
member: {
email: 'user@example.com',
name: 'John Doe',
phone: '+1234567890',
dateOfBirth: '1990-05-15', // ISO date
avatarUrl: 'https://example.com/avatar.jpg',
metadata: {
tier: 'gold',
preferences: { newsletter: true }
}
}Member Data Object
interface MemberData {
email?: string;
name?: string;
phone?: string;
dateOfBirth?: string; // YYYY-MM-DD format
avatarUrl?: string;
metadata?: Record<string, unknown>;
}| Field | Type | Description |
|---|---|---|
email | string | Member's email address |
name | string | Display name |
phone | string | Phone number |
dateOfBirth | string | Birth date for birthday bonuses |
avatarUrl | string | Profile image URL |
metadata | object | Custom key-value data |
Callbacks
onReady
Called when the widget is fully loaded and ready.
onReady: () => {
console.log("Widget ready");
// Enable related UI elements
document.querySelector("#loyalty-link").classList.remove("hidden");
};onError
Called when an error occurs during initialization.
onError: (error) => {
console.error("Widget error:", error.message);
// Show fallback UI or retry
if (error.message.includes("network")) {
showRetryButton();
}
};onWelcomeBonus
Called when a new member receives their welcome bonus.
onWelcomeBonus: (points) => {
// Show celebration
showToast(`Welcome! You've earned ${points} points!`);
// Track analytics
analytics.track("welcome_bonus_received", { points });
};Theme Object
interface WidgetTheme {
primaryColor?: string;
backgroundColor?: string;
textColor?: string;
fontFamily?: string;
position?: "left" | "right";
borderRadius?: string;
hideQuests?: boolean;
hidePromo?: boolean;
hideBadges?: boolean;
hideRefer?: boolean;
launcher?: LauncherConfig;
}
interface LauncherConfig {
displayMode?: "floating" | "custom";
variant?: "icon-only" | "icon-text";
icon?: "gift" | "star" | "coin" | "award";
text?: string;
size?: number;
offset?: { x?: number; y?: number };
pulse?: boolean;
}| Option | Type | Default | Description |
|---|---|---|---|
primaryColor | string | #6366f1 | Primary brand color |
backgroundColor | string | #ffffff | Widget background |
textColor | string | #1e293b | Text color |
fontFamily | string | System fonts | Font stack |
position | string | right | Launcher position |
borderRadius | string | 16px | Corner radius |
hideQuests | boolean | false | Hide quests tab |
hidePromo | boolean | false | Hide promo input |
hideBadges | boolean | false | Hide badges |
hideRefer | boolean | false | Hide referral tab |
Launcher Configuration
The launcher option controls how the widget trigger button appears and behaves.
Display Modes
| Mode | Description |
|---|---|
floating | Shows a floating button (default) |
custom | No launcher button - use UseLoyaltyWidget.open() from your own UI |
Launcher Options
| Option | Type | Default | Description |
|---|---|---|---|
displayMode | string | floating | floating or custom |
variant | string | icon-only | icon-only or icon-text |
icon | string | gift | Icon: gift, star, coin, award |
text | string | Rewards | Text label (for icon-text variant) |
size | number | 56 | Button size in pixels |
offset | object | {x:24, y:24} | Distance from screen edge |
pulse | boolean | false | Enable attention-grabbing pulse animation |
Floating Button Examples
// Default floating button
UseLoyaltyWidget.init({
...auth,
theme: {
launcher: {
displayMode: "floating",
variant: "icon-only",
icon: "gift",
},
},
});
// Button with text label
UseLoyaltyWidget.init({
...auth,
theme: {
launcher: {
displayMode: "floating",
variant: "icon-text",
icon: "star",
text: "Earn Points",
pulse: true, // Draws attention
},
},
});Custom Trigger Mode
Hide the floating button and trigger the widget from your own UI:
// Initialize without visible launcher
UseLoyaltyWidget.init({
...auth,
theme: {
launcher: {
displayMode: "custom",
},
},
});
// Trigger from your own button
document.querySelector("#my-rewards-btn").addEventListener("click", () => {
UseLoyaltyWidget.open();
});
// Or toggle open/closed
document.querySelector("#toggle-btn").addEventListener("click", () => {
UseLoyaltyWidget.toggle();
});This is useful when you want to:
- Add the trigger to your navigation menu
- Use a custom-styled button
- Open the widget based on user actions (e.g., after purchase)
- Integrate with existing reward/loyalty UI elements
Full Example
UseLoyaltyWidget.init({
// Authentication
publicKey: "pk_live_abc123",
externalId: user.id,
timestamp: Date.now(),
signature: authResponse.signature,
// API
apiUrl: "https://app.useloyalty.app",
// Appearance
theme: {
primaryColor: "#2563eb",
backgroundColor: "#ffffff",
textColor: "#0f172a",
fontFamily: "Inter, system-ui, sans-serif",
position: "right",
borderRadius: "12px",
hidePromo: false,
launcher: {
size: 56,
offset: { x: 20, y: 20 },
},
},
// Language
language: "en",
// Member Data
member: {
email: user.email,
name: user.name,
avatarUrl: user.avatar,
dateOfBirth: user.birthday,
metadata: {
plan: user.subscription,
signupSource: "web",
},
},
// Callbacks
onReady: () => {
console.log("useLoyalty widget ready");
trackEvent("widget_loaded");
},
onError: (error) => {
console.error("useLoyalty widget error:", error);
reportError(error);
},
onWelcomeBonus: (points) => {
showNotification(`Welcome! +${points} points`);
},
});Environment-Based Config
const config = {
development: {
apiUrl: "http://localhost:3000",
publicKey: process.env.USELOYALTY_PUBLIC_KEY_DEV,
},
production: {
apiUrl: "https://app.useloyalty.app",
publicKey: process.env.USELOYALTY_PUBLIC_KEY_PROD,
},
};
const env = process.env.NODE_ENV || "development";
UseLoyaltyWidget.init({
...config[env],
externalId: user.id,
timestamp: auth.timestamp,
signature: auth.signature,
});Feature Flags
Control widget features via theme options:
// Minimal widget - rewards only
UseLoyaltyWidget.init({
...auth,
theme: {
hideQuests: true,
hideRefer: true,
hideBadges: true,
hidePromo: true,
},
});
// Full featured widget
UseLoyaltyWidget.init({
...auth,
theme: {
hideQuests: false,
hideRefer: false,
hideBadges: false,
hidePromo: false,
},
});