Advanced Embedding Settings

This guide covers advanced configuration options for the Public AI Chat widget, including consent management, programmatic control, custom positioning, and dynamic configuration updates.

Purpose

This document provides detailed instructions for advanced features of the Public AI Chat widget, including:

  • GDPR-compliant consent management
  • Programmatic widget control
  • Custom positioning and styling
  • Dynamic configuration updates
  • Integration with custom UI elements

Scope

Covered

  • Consent management (basic and GDPR-compliant)
  • Programmatic widget control (open, close, toggle)
  • Hiding/showing the floating action button
  • Custom positioning options
  • Dark mode control
  • Sending messages programmatically
  • User information association
  • Dynamic configuration updates

Not Covered

Prerequisites

  • Public AI Chat widget already embedded on your website
  • Basic understanding of JavaScript
  • Access to modify your website's HTML and JavaScript

The widget supports GDPR-compliant consent management, allowing you to delay initialization until consent is granted and control storage behavior based on consent status.

Delay widget initialization until consent is granted:

<script>
  // Set initial consent state
  window.hasConsent = false;
  
  // Grant consent when user accepts
  function grantConsent() {
    window.hasConsent = true;
    // Widget will initialize automatically
  }
</script>

<div
  data-clearideas-widget
  data-access-key="your-access-key"
  data-has-consent="hasConsent"
></div>

Or programmatically:

function checkConsent() {
  // Check your consent mechanism (cookie, localStorage, etc.)
  return localStorage.getItem('consent') === 'granted';
}

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  hasConsent: checkConsent // Can be: true, false, function, or string (global var name)
});

For GDPR compliance, use consentRequired and consentGranted to control storage behavior:

  • When consent not required or granted: Widget uses localStorage and sends cookies
  • When consent required but not granted: Widget uses sessionStorage only, no cookies sent
  • On consent grant: Widget automatically migrates from sessionStorage to localStorage
// Determine if consent is required (e.g., based on user location)
const consentRequired = isGDPRRegion(); // Your geo-detection logic

// Initialize widget with consent state
const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  consentRequired: consentRequired,
  consentGranted: false, // Initially no consent
});

// When user grants consent
function grantConsent() {
  widget.setConsentGranted(true);
  // Widget automatically migrates storage and re-initializes
}

// When user revokes consent
function revokeConsent() {
  widget.setConsentGranted(false);
  // Widget switches back to sessionStorage only
}

Using Data Attributes:

<div
  data-clearideas-widget
  data-access-key="your-access-key"
  data-consent-required="true"
  data-consent-granted="false"
></div>

Manually Launching the Widget

You can control when the widget opens programmatically instead of relying on the floating action button:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  openOnLoad: false, // Don't open automatically
});

// Open the widget when your button is clicked
document.getElementById('my-chat-button').addEventListener('click', () => {
  widget.open();
});

// Or toggle it
document.getElementById('toggle-chat').addEventListener('click', () => {
  widget.toggle();
});

Hiding the Floating Action Button

Hide the default floating action button and use your own custom button or menu to control the widget:

<!-- Hide the FAB -->
<div
  data-clearideas-widget
  data-access-key="your-access-key"
  data-fab-hide="true"
></div>

<!-- Your custom button -->
<button id="my-chat-button" onclick="widget.toggle()">
  Open Chat
</button>

<script>
  const widget = window.ClearIdeasWidget.init({
    accessKey: 'your-access-key',
    fabHide: true, // Hide the floating action button
  });
</script>

You can also hide/show the FAB dynamically:

widget.hide(); // Hide the floating action button
widget.show(); // Show the floating action button

Custom Positioning

Use absolute positioning for custom placement instead of the default corner positions:

<!-- Using data attributes -->
<div
  data-clearideas-widget
  data-access-key="your-access-key"
  data-top="100"
  data-right="50"
></div>

Or programmatically:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  top: 100,    // Distance from top in pixels
  right: 50,   // Distance from right in pixels
  // When top/right/bottom/left are set, position is ignored
});

// To clear absolute positioning and return to corner positioning:
widget.setTop(undefined);
widget.setRight(undefined);
widget.setBottom(undefined);
widget.setLeft(undefined);
widget.setPosition('bottom-right'); // Set desired corner position

Custom Floating Action Button Size

Adjust the size of the floating action button:

<div
  data-clearideas-widget
  data-access-key="your-access-key"
  data-fab-size="64"
></div>

Or programmatically:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  fabSize: 64, // Larger button (default: 56px)
});

Dark Mode Control

Control dark mode programmatically or sync with your website's theme:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  darkMode: false, // Initial value
});

// Update dark mode when user toggles it
document.getElementById('dark-mode-toggle').addEventListener('change', (e) => {
  widget.setDarkMode(e.target.checked);
});

Or sync with your website's dark mode:

// Detect system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  darkMode: prefersDark,
});

// Listen for changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
  widget.setDarkMode(e.matches);
});

Sending Messages Programmatically

Send messages to the chat programmatically. The widget must be initialized and the chat should be open:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
});

// Open the widget first (optional, but recommended for better UX)
widget.open();

// Send a message (returns a Promise)
try {
  await widget.sendMessage('Hello! I have a question about your product.');
  console.log('Message sent successfully');
} catch (error) {
  console.error('Failed to send message:', error);
}

User Information

Associate user information with chat sessions:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  userName: 'John Doe',
  userEmail: 'john@example.com',
  userId: 'user-123',
});

// Update user info when user logs in
function onUserLogin(user) {
  widget.setUserName(user.name);
  widget.setUserEmail(user.email);
  widget.setUserId(user.id);
}

// Clear user info when user logs out
function onUserLogout() {
  widget.setUserName(undefined);
  widget.setUserEmail(undefined);
  widget.setUserId(undefined);
}

Dynamic Configuration Updates

Update widget configuration dynamically using setter methods:

const widget = window.ClearIdeasWidget.init({
  accessKey: 'your-access-key',
  width: 380,
  height: 540,
  position: 'bottom-right',
});

// Update size when window resizes
window.addEventListener('resize', () => {
  if (window.innerWidth < 768) {
    widget.setWidth(320);
    widget.setHeight(480);
  } else {
    widget.setWidth(380);
    widget.setHeight(540);
  }
});

// Update position
widget.setPosition('top-left');

// Update consent
widget.setConsentGranted(true);
widget.setConsentRequired(true);

Complete Advanced Example

Here's a complete example combining multiple advanced features:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://updates.clearideas.com/chat.css">
</head>
<body>
  <!-- Custom chat button -->
  <button id="chat-button">Chat with Us</button>
  
  <script src="https://updates.clearideas.com/chat.js"></script>
  <script>
    // Wait for widget script to load, then initialize
    document.addEventListener('DOMContentLoaded', function() {
      // Initialize widget with advanced configuration
      const widget = window.ClearIdeasWidget.init({
        accessKey: 'your-access-key',
        apiBaseUrl: 'https://api.clearideas.com', // Optional, defaults to https://api.clearideas.com
        fabHide: true, // Hide default FAB
        openOnLoad: false, // Don't open automatically
        consentRequired: true, // GDPR compliance
        consentGranted: false, // Initially no consent
        darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,
      });
      
      // Custom button to open chat
      document.getElementById('chat-button').addEventListener('click', () => {
        widget.open();
      });
      
      // Grant consent when user accepts
      function grantConsent() {
        widget.setConsentGranted(true);
      }
      
      // Revoke consent when user revokes
      function revokeConsent() {
        widget.setConsentGranted(false);
      }
      
      // Update user info when logged in
      function onUserLogin(user) {
        widget.setUserName(user.name);
        widget.setUserEmail(user.email);
        widget.setUserId(user.id);
      }
      
      // Clear user info when logged out
      function onUserLogout() {
        widget.setUserName(undefined);
        widget.setUserEmail(undefined);
        widget.setUserId(undefined);
      }
      
      // Sync dark mode with system preference
      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
        widget.setDarkMode(e.matches);
      });
    });
  </script>
</body>
</html>

Alternative initialization pattern (if script loads synchronously):

<script src="https://updates.clearideas.com/chat.js"></script>
<script>
  // Initialize immediately if script is loaded synchronously
  const widget = window.ClearIdeasWidget.init({
    accessKey: 'your-access-key',
    fabHide: true,
    openOnLoad: false,
    consentRequired: true,
    consentGranted: false,
    darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,
  });
  
  // Set up event handlers
  document.getElementById('chat-button').addEventListener('click', () => {
    widget.open();
  });
</script>

Widget Instance API Reference

After initialization, the widget instance provides the following methods:

Control Methods

  • open(): Opens the widget
  • close(): Closes the widget
  • toggle(): Toggles widget open/closed state
  • sendMessage(content: string): Sends a message programmatically
  • hide(): Hides the floating action button
  • show(): Shows the floating action button
  • destroy(): Removes the widget from the DOM

Setter Methods

All configuration options can be updated dynamically:

  • setDarkMode(isDark: boolean): Enable or disable dark mode
  • setConsentRequired(required: boolean): Set whether consent is required
  • setConsentGranted(granted: boolean): Set consent granted status
  • setPosition(position: string): Set widget position ('bottom-right', 'bottom-left', 'top-right', 'top-left')
  • setWidth(width: number): Set widget width in pixels
  • setHeight(height: number): Set widget height in pixels
  • setTop(top: number | undefined): Set absolute positioning from top
  • setRight(right: number | undefined): Set absolute positioning from right
  • setBottom(bottom: number | undefined): Set absolute positioning from bottom
  • setLeft(left: number | undefined): Set absolute positioning from left
  • setFabSize(size: number): Set floating action button size in pixels
  • setUserName(name: string | undefined): Set user name
  • setUserEmail(email: string | undefined): Set user email
  • setUserId(id: string | undefined): Set user ID

Best Practices

  • Always check consent before initializing the widget in GDPR regions
  • Use setConsentGranted() instead of destroying and re-initializing when consent changes
  • Monitor consent status and update the widget accordingly

Performance

  • Use setter methods for dynamic updates instead of re-initializing the widget
  • Cache the widget instance to avoid multiple initializations
  • Clean up event listeners when the widget is destroyed

User Experience

  • Provide clear UI controls for opening/closing the widget
  • Sync dark mode with your website's theme for consistency
  • Update user information when users log in or out