Advanced Features
Overview
Section titled “Overview”The SiteAssist widget includes several advanced features that enhance user experience and provide powerful capabilities beyond basic chat functionality.
Text Selection & Context
Section titled “Text Selection & Context”One of the most powerful features of the SiteAssist widget is intelligent text selection. Users can select any text on your page and instantly ask the AI about it.
How It Works
Section titled “How It Works”- User selects text on your page
- An “Ask AI” popover appears near the selection
- User clicks the popover
- Widget opens with the selected text as context
- AI provides answers based on both the selection and page content
Automatic Context Sharing
Section titled “Automatic Context Sharing”The widget automatically shares page context with the AI, including:
- Page URL: Current page location
- Page Title: Document title
- Page Content: Cleaned, text-only version of page content
- Selected Text: Any text the user has selected (if using text selection feature)
What gets filtered out:
- Scripts and styles
- Navigation menus
- Advertisements
- SVG and canvas elements
- Media elements (audio, video, images)
- The widget itself
Example Use Cases
Section titled “Example Use Cases”Documentation Sites:
User selects: "To install the package, run npm install..."User asks: "What does this command do?"AI responds with context-aware explanationE-commerce:
User selects: "Free shipping on orders over $50"User asks: "How can I get free shipping?"AI explains the shipping policyBlog Posts:
User selects: "The React useEffect hook..."User asks: "Can you explain this in simpler terms?"AI provides a simplified explanationControlling Text Selection Areas
Section titled “Controlling Text Selection Areas”You can control where the text selection popover appears using the contentSelector option:
// Default - only show popover in .main-content elementsSiteAssist("init", { apiKey: "YOUR_API_KEY", contentSelector: true, // or omit entirely});
// Show popover everywhere on the pageSiteAssist("init", { apiKey: "YOUR_API_KEY", contentSelector: false,});
// Custom selector - only in specific areasSiteAssist("init", { apiKey: "YOUR_API_KEY", contentSelector: ".main-content",});Use Cases:
- Documentation sites: Restrict to main content areas to avoid confusion
- Blogs: Only allow selection in article content, not navigation
- E-commerce: Enable everywhere for product help and support
- Admin panels: Restrict to specific content sections
Example HTML Structure:
<div class="sidebar"> <nav> <a href="/">Home</a> <a href="/docs">Docs</a> </nav> <!-- Text selection popover won't appear here --></div>
<div class="main-content"> <h1>Documentation</h1> <p>Select this text to ask AI questions!</p> <!-- Text selection popover WILL appear here --></div>Fullscreen Mode
Section titled “Fullscreen Mode”The widget supports fullscreen mode for immersive chat experiences.
Automatic Fullscreen
Section titled “Automatic Fullscreen”Fullscreen is automatically activated on:
- Mobile devices (screens < 768px wide)
- When user clicks fullscreen button in widget
Manual Fullscreen Control
Section titled “Manual Fullscreen Control”The widget can request fullscreen mode, which is handled automatically:
// Widget internally handles fullscreen requests// No manual API needed - users control via widget UIFullscreen Behavior
Section titled “Fullscreen Behavior”When fullscreen is active:
- Widget expands to fill entire viewport
- Page scrolling is disabled (
overflow: hidden) - Close button remains accessible
- User can exit via close button or ESC key
When fullscreen exits:
- Widget returns to normal size
- Page scrolling is restored
- Content layout returns to normal
Responsive Breakpoints
Section titled “Responsive Breakpoints”The widget uses these breakpoints:
- Mobile (
< 768px): Always fullscreen when open - Tablet (
768px - 1024px): Standard size, can go fullscreen - Desktop (
≥ 1024px): Standard size with sidepanel support
Page Context Integration
Section titled “Page Context Integration”The widget automatically integrates with your page content to provide intelligent, context-aware responses.
Context Extraction
Section titled “Context Extraction”When a user interacts with the widget, it automatically extracts:
{ url: "https://yoursite.com/page", title: "Page Title", content: "Clean text content of the page...", textSelection: "Selected text (if any)"}How Content is Cleaned
Section titled “How Content is Cleaned”The widget intelligently cleans page content:
- Clone the document body
- Remove unnecessary elements (scripts, styles, widgets, media)
- Extract link text and URLs:
"Link Text (https://url)" - Normalize whitespace and line breaks
- Send to AI for context-aware responses
Example Context Usage
Section titled “Example Context Usage”User visits: https://example.com/pricing
// Automatically shared context:{ url: "https://example.com/pricing", title: "Pricing - Example SaaS", content: "Pricing Plans Starter $9/month Basic features... Pro $29/month Advanced features...", textSelection: null}User asks: “What’s included in the Pro plan?”
AI receives context and can answer specifically about that page’s Pro plan.
Privacy Considerations
Section titled “Privacy Considerations”What is shared:
- Publicly visible text content
- Page URL and title
- User’s selected text
What is NOT shared:
- Form inputs or user data
- Hidden or password-protected content
- Images or media files
- Scripts or technical implementation
Custom Events
Section titled “Custom Events”The widget dispatches custom events that you can listen to for advanced integrations.
Event Format
Section titled “Event Format”All custom events are prefixed with sa: and dispatched on the window object:
window.addEventListener("sa:event_name", (event) => { console.log("Event detail:", event.detail);});Common Events
Section titled “Common Events”While specific events depend on your widget configuration, you can listen for custom events:
// Example: Listen for chat openedwindow.addEventListener("sa:opened", () => { console.log("Chat widget opened"); // Track in your analytics analytics.track("Chat Opened");});
// Example: Listen for chat closedwindow.addEventListener("sa:closed", () => { console.log("Chat widget closed");});
// Example: Custom event from widgetwindow.addEventListener("sa:custom_action", (event) => { console.log("Custom action:", event.detail);});Event-Driven Integrations
Section titled “Event-Driven Integrations”Example - Track widget usage:
let chatOpenedAt = null;
window.addEventListener("sa:opened", () => { chatOpenedAt = Date.now(); console.log("Chat opened");});
window.addEventListener("sa:closed", () => { if (chatOpenedAt) { const duration = Date.now() - chatOpenedAt; console.log(`Chat was open for ${duration}ms`); chatOpenedAt = null; }});Example - Trigger other UI elements:
window.addEventListener("sa:opened", () => { // Hide other overlays when chat opens document.getElementById("promo-banner").style.display = "none";});
window.addEventListener("sa:closed", () => { // Show promo banner again document.getElementById("promo-banner").style.display = "block";});Responsive Behavior
Section titled “Responsive Behavior”The widget automatically adapts to different screen sizes and orientations.
Mobile Optimization
Section titled “Mobile Optimization”On mobile devices (< 768px):
- Widget opens in fullscreen
- “Ask AI” text selection popover is optimized for touch
- Page scrolling disabled when widget is open
- Swipe gestures for closing (native behavior)
Tablet Behavior
Section titled “Tablet Behavior”On tablets (768px - 1024px):
- Standard widget size
- Sidepanel floats over content (doesn’t push)
- Touch-optimized interactions
- Responsive text selection
Desktop Experience
Section titled “Desktop Experience”On desktop (≥ 1024px):
- Full-featured experience
- Sidepanel can push content
- Keyboard shortcuts work
- Precise text selection
Orientation Changes
Section titled “Orientation Changes”The widget automatically handles orientation changes:
// Automatically handled - no code needed// Widget adjusts when device rotatesSidepanel Integration
Section titled “Sidepanel Integration”The sidepanel widget type offers advanced integration with your application layout.
Content Push Behavior
Section titled “Content Push Behavior”When sidepanel opens on desktop screens:
SiteAssist("init", { apiKey: "YOUR_API_KEY", type: "sidepanel", appContainerSelector: ".main-content",});Desktop (≥ 1024px):
- Container margin-right:
400px - Smooth transition animation
- Content visible alongside widget
Tablet (< 1024px):
- Sidepanel floats over content
- No content push
- Overlay-style interaction
Mobile (< 768px):
- Full-screen mode
- Content hidden while widget open
Multiple Containers
Section titled “Multiple Containers”You can have multiple containers that respond to the sidepanel:
<div class="siteassist-container"> <header>Header content</header></div>
<div class="siteassist-container"> <main>Main content</main></div>
<div class="siteassist-container"> <footer>Footer content</footer></div>All containers with the class will be pushed when the sidepanel opens.
Custom Transition
Section titled “Custom Transition”The widget applies default transitions, but you can customize:
.siteassist-container { transition-property: margin-right; transition-duration: 200ms; transition-timing-function: ease-in-out;}Performance Optimization
Section titled “Performance Optimization”The widget is designed for optimal performance:
Async Loading
Section titled “Async Loading”The widget loads asynchronously and doesn’t block page rendering:
// Non-blocking async loado.async = !0;o.src = "https://...widget.js";e.head.appendChild(o);Lazy Initialization
Section titled “Lazy Initialization”The iframe content only loads when:
- Widget is initialized
- User first interacts with the widget
Resource Optimization
Section titled “Resource Optimization”- Small bundle size: ~10KB gzipped
- No external dependencies: Self-contained
- Efficient event handlers: Debounced and throttled
- Smart content extraction: Only when needed
Security Best Practices
Section titled “Security Best Practices”Publishable Key Protection
Section titled “Publishable Key Protection”// ✅ Good - use environment variablesSiteAssist("init", { apiKey: process.env.NEXT_PUBLIC_SITEASSIST_PUBLISHABLE_KEY,});
// ❌ Avoid - hardcoded keys in public reposSiteAssist("init", { apiKey: "pk_live_hardcoded_key_123", // Don't commit this!});Content Security Policy (CSP)
Section titled “Content Security Policy (CSP)”If you use CSP headers, whitelist these domains:
script-src 'self' https://cnrib24ur3hk4b49.public.blob.vercel-storage.com;frame-src https://widgets.siteassist.io;connect-src https://api.siteassist.io;Cross-Origin Communication
Section titled “Cross-Origin Communication”The widget uses secure postMessage communication:
// Widget validates message originif (ev.origin !== options.widgetUrl) return;Advanced Customization Examples
Section titled “Advanced Customization Examples”Custom Trigger Button
Section titled “Custom Trigger Button”Replace default floating button with your own:
<style> .sa-button { display: none !important; } /* Hide default button */</style>
<button id="custom-chat-button" class="your-button-class"> 💬 Chat with AI</button>
<script> SiteAssist("init", { apiKey: "YOUR_API_KEY", type: "floating-bubble", });
document .getElementById("custom-chat-button") .addEventListener("click", () => { SiteAssist("toggle"); });</script>Conditional Loading
Section titled “Conditional Loading”Load widget only for specific pages or users:
// Only load on product pagesif (window.location.pathname.startsWith("/products/")) { SiteAssist("init", { apiKey: "YOUR_API_KEY", });}
// Only for logged-in usersif (userIsLoggedIn) { SiteAssist("init", { apiKey: "YOUR_API_KEY", externalId: currentUser.id, });}Theme Synchronization
Section titled “Theme Synchronization”Sync widget theme with your site:
// Watch for site theme changesconst observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.attributeName === "data-theme") { const theme = document.documentElement.getAttribute("data-theme"); SiteAssist("changeTheme", theme); } });});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"],});Troubleshooting
Section titled “Troubleshooting”Text Selection Not Working
Section titled “Text Selection Not Working”Check:
- Widget is properly initialized
- No conflicting JavaScript on the page
- Browser supports Selection API
- Content selector is correctly configured
Debug:
window.addEventListener("mouseup", () => { const selection = window.getSelection(); console.log("Selected text:", selection.toString());
// Check if selection is in the right area const range = selection.getRangeAt(0); const container = range.commonAncestorContainer; console.log("Selection container:", container);});Common Issues:
- Popover not appearing: Check your
contentSelectorsetting - Popover appears in wrong areas: Verify your CSS selector is correct
- Selection not working at all: Ensure widget is properly initialized
Example debugging:
// Test if contentSelector is workingSiteAssist("init", { apiKey: "YOUR_API_KEY", contentSelector: ".test-area", // Test with a specific area});
// Check if the selector existsconsole.log("Content element found:", document.querySelector(".test-area"));Fullscreen Issues
Section titled “Fullscreen Issues”Common causes:
- Browser restrictions on fullscreen
- Conflicting CSS
overflowproperties - Z-index conflicts
Solution:
/* Ensure widget has high z-index */.sa-frame.fullscreen { z-index: 999999 !important;}Content Not Being Captured
Section titled “Content Not Being Captured”Check:
- Page content isn’t in an iframe
- Content is rendered (not dynamically loaded after widget init)
- No security restrictions
Next Steps
Section titled “Next Steps”- Examples - See real-world implementation examples
- API Reference - Complete API documentation
- Configuration - Customization options
Need help with advanced features? Contact us at support@siteassist.io