Skip to main content

Customization Guide

Learn how to customize the appearance and behavior of the Traise Widget to match your application's needs.

Theme Customization

Built-in Themes

The widget comes with two built-in themes:

// Light theme (default)
TraiseWidget.init({
apiKey: 'your-api-key',
mode: 'light'
});

// Dark theme
TraiseWidget.init({
apiKey: 'your-api-key',
mode: 'dark'
});

Dynamic Theme Switching

Change themes at runtime:

// Switch to dark theme
TraiseWidget.updateConfig({ mode: 'dark' });

// Switch back to light theme
TraiseWidget.updateConfig({ mode: 'light' });

// React to system theme
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
TraiseWidget.updateConfig({
mode: mediaQuery.matches ? 'dark' : 'light'
});

mediaQuery.addEventListener('change', (e) => {
TraiseWidget.updateConfig({
mode: e.matches ? 'dark' : 'light'
});
});

Position Customization

Built-in Positions

The widget supports four corner positions:

// Bottom right (default)
TraiseWidget.init({
apiKey: 'your-api-key',
position: 'bottom-right'
});

// Other positions
TraiseWidget.updateConfig({ position: 'bottom-left' });
TraiseWidget.updateConfig({ position: 'top-right' });
TraiseWidget.updateConfig({ position: 'top-left' });

Dynamic Position Changes

// Change position based on viewport
function updatePosition() {
const isMobile = window.innerWidth < 768;
TraiseWidget.updateConfig({
position: isMobile ? 'bottom-right' : 'bottom-left'
});
}

window.addEventListener('resize', updatePosition);
updatePosition();

Behavioral Customization

Auto-Show Widget

// Show widget automatically after page load
setTimeout(() => {
TraiseWidget.show();
}, 5000); // 5 seconds delay

// Show based on user behavior
let scrollCount = 0;
window.addEventListener('scroll', () => {
scrollCount++;
if (scrollCount >= 3 && !TraiseWidget.getStatus().visible) {
TraiseWidget.show();
}
});

// Show on specific pages
if (window.location.pathname === '/contact') {
setTimeout(() => TraiseWidget.show(), 2000);
}

Event-Based Customization

// React to widget events
TraiseWidget.on('widgetShown', () => {
console.log('Widget opened');
// Track analytics event
});

TraiseWidget.on('widgetHidden', () => {
console.log('Widget closed');
});

TraiseWidget.on('messageReceived', (message) => {
// Play notification sound
const audio = new Audio('/sounds/notification.mp3');
audio.play();
});

TraiseWidget.on('callStarted', (call) => {
console.log('Call initiated to:', call.phoneNumber);
});

Keyboard Shortcuts

// Custom keyboard shortcuts
document.addEventListener('keydown', (e) => {
// Ctrl/Cmd + Shift + C to toggle widget
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'C') {
e.preventDefault();
const status = TraiseWidget.getStatus();
if (status.visible) {
TraiseWidget.hide();
} else {
TraiseWidget.show();
}
}

// Escape to close widget
if (e.key === 'Escape' && TraiseWidget.getStatus().visible) {
TraiseWidget.hide();
}
});

Debug Mode

Enable debug mode for development and troubleshooting:

TraiseWidget.init({
apiKey: 'your-api-key',
debug: true // Shows debug panel and verbose logging
});

// Toggle debug mode at runtime
const currentConfig = TraiseWidget.getConfig();
TraiseWidget.updateConfig({
debug: !currentConfig.debug
});

// Access debug panel with Shift+D when widget is open

Demo Mode

Use demo mode for testing without connecting to backend services:

TraiseWidget.init({
apiKey: 'demo-key',
demoMode: true // Uses simulated data
});

Performance Optimization

Lazy Loading

// Load widget only when needed
let widgetLoaded = false;

async function loadWidget() {
if (!widgetLoaded) {
const { init, show } = await import('traise-widget');
await init({ apiKey: 'your-api-key' });
show();
widgetLoaded = true;
}
}

// Load on user interaction
document.querySelector('#support-button').addEventListener('click', loadWidget);

// Or load on scroll
window.addEventListener('scroll', loadWidget, { once: true });

Conditional Loading

// Only load widget for logged-in users
if (user.isAuthenticated) {
TraiseWidget.init({ apiKey: 'your-api-key' });
}

// Load based on business hours
const hour = new Date().getHours();
if (hour >= 9 && hour < 17) {
TraiseWidget.init({ apiKey: 'your-api-key' });
}

Client Context

Preload client information for personalized experience:

// Load client data on initialization
TraiseWidget.init({
apiKey: 'your-api-key'
}).then(widget => {
if (widget && user.isAuthenticated) {
TraiseWidget.loadClient({
name: user.name,
phoneNumber: user.phone,
email: user.email
});
}
});

// Update client context dynamically
TraiseWidget.loadClient({
name: 'John Doe',
phoneNumber: '+1234567890'
});

Testing Configurations

// Test different configurations
const configs = [
{ mode: 'light', position: 'bottom-right' },
{ mode: 'dark', position: 'bottom-left' },
{ mode: 'light', position: 'top-right' },
{ mode: 'dark', position: 'top-left' }
];

let currentConfig = 0;

function rotateConfig() {
TraiseWidget.updateConfig(configs[currentConfig]);
currentConfig = (currentConfig + 1) % configs.length;
console.log('Applied config:', configs[currentConfig - 1]);
}

// Rotate configurations for testing
// rotateConfig(); // Uncomment to test

Common Patterns

Support Hours Indicator

// Show widget only during support hours
function isWithinSupportHours() {
const now = new Date();
const day = now.getDay();
const hour = now.getHours();

// Monday-Friday, 9 AM - 5 PM
return day >= 1 && day <= 5 && hour >= 9 && hour < 17;
}

if (isWithinSupportHours()) {
TraiseWidget.init({ apiKey: 'your-api-key' });
} else {
console.log('Support widget not available outside business hours');
}

Page-Specific Behavior

// Different behavior for different pages
const pageConfigs = {
'/': { position: 'bottom-right', mode: 'light' },
'/pricing': { position: 'bottom-left', mode: 'light' },
'/contact': { position: 'top-right', mode: 'dark', autoShow: true }
};

const currentPath = window.location.pathname;
const config = pageConfigs[currentPath] || pageConfigs['/'];

TraiseWidget.init({
apiKey: 'your-api-key',
...config
});

if (config.autoShow) {
setTimeout(() => TraiseWidget.show(), 1000);
}

Next Steps