Implementation Examples
Overview
Section titled “Overview”This guide provides complete, real-world examples of integrating the SiteAssist widget in various scenarios and platforms.
Basic Examples
Section titled “Basic Examples”Simple Website
Section titled “Simple Website”The most straightforward integration for a basic website:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>My Website</title>
<!-- SiteAssist Widget --> <script type="text/javascript"> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist"); </script>
<script type="text/javascript"> SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", }); </script> </head> <body> <h1>Welcome to My Website</h1> <p>Your content here...</p> </body></html>Framework Examples
Section titled “Framework Examples”Next.js (App Router)
Section titled “Next.js (App Router)”File: app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children,}: { children: React.ReactNode;}) { return ( <html lang="en"> <body> {children}
{/* SiteAssist Widget Loader */} <Script id="siteassist-loader" strategy="afterInteractive"> {` !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist"); `} </Script>
{/* Initialize SiteAssist */} <Script id="siteassist-init" strategy="afterInteractive"> {` SiteAssist("init", { apiKey: "${process.env.NEXT_PUBLIC_SITEASSIST_PUBLISHABLE_KEY}", theme: "auto" }); `} </Script> </body> </html> );}With environment variables:
NEXT_PUBLIC_SITEASSIST_PUBLISHABLE_KEY=pk_live_abc123Next.js (Pages Router)
Section titled “Next.js (Pages Router)”File: pages/_app.tsx
import type { AppProps } from "next/app";import Script from "next/script";
export default function App({ Component, pageProps }: AppProps) { return ( <> <Component {...pageProps} />
<Script id="siteassist-loader" strategy="afterInteractive"> {` !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist"); `} </Script>
<Script id="siteassist-init" strategy="afterInteractive"> {` SiteAssist("init", { apiKey: "${process.env.NEXT_PUBLIC_SITEASSIST_PUBLISHABLE_KEY}", theme: "auto" }); `} </Script> </> );}File: App.tsx
import { useEffect } from "react";
function App() { useEffect(() => { // Load SiteAssist script if (!window.SiteAssist) { const loader = document.createElement("script"); loader.innerHTML = ` !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist"); `; document.head.appendChild(loader);
// Initialize const init = document.createElement("script"); init.innerHTML = ` SiteAssist("init", { apiKey: "${import.meta.env.VITE_SITEASSIST_API_KEY}", theme: "auto" }); `; document.head.appendChild(init); } }, []);
return <div className="App">{/* Your app content */}</div>;}
export default App;Alternative: Using public/index.html
<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8" /> <title>React App</title>
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "%VITE_SITEASSIST_API_KEY%", theme: "auto", }); </script> </head> <body> <div id="root"></div> </body></html>Vue.js
Section titled “Vue.js”File: index.html or app.html
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vue App</title>
<script> !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist");
SiteAssist("init", { apiKey: import.meta.env.VITE_SITEASSIST_API_KEY, theme: "auto" }); </script> </head> <body> <div id="app"></div> </body></html>Angular
Section titled “Angular”File: src/index.html
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <title>Angular App</title> <base href="/" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist"); </script> </head> <body> <app-root></app-root>
<script> // Initialize after Angular loads SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", }); </script> </body></html>Platform-Specific Examples
Section titled “Platform-Specific Examples”WordPress (Theme Integration)
Section titled “WordPress (Theme Integration)”File: header.php
<!DOCTYPE html><html <?php language_attributes(); ?>><head> <meta charset="<?php bloginfo('charset'); ?>"> <meta name="viewport" content="width=device-width, initial-scale=1"> <?php wp_head(); ?>
<!-- SiteAssist Widget --> <script type="text/javascript"> !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist");
SiteAssist("init", { apiKey: "<?php echo get_option('siteassist_api_key'); ?>", theme: "auto" }); </script></head>Alternative: Using functions.php
<?phpfunction add_siteassist_widget() { $api_key = get_option('siteassist_api_key'); if (empty($api_key)) return; ?> <script type="text/javascript"> !function(t,e,c,n,s){if(t[s])return;const i=t[s]=function(){i._q.push(arguments)};i._q=[];const o=e.createElement("script");o.async=!0,o.src="https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js",e.head.appendChild(o)}(window,document,0,0,"SiteAssist");
SiteAssist("init", { apiKey: "<?php echo esc_js($api_key); ?>", theme: "auto" }); </script> <?php}add_action('wp_head', 'add_siteassist_widget');?>Advanced Use Cases
Section titled “Advanced Use Cases”SaaS Dashboard with Sidepanel
Section titled “SaaS Dashboard with Sidepanel”Perfect for web applications and admin panels:
<!DOCTYPE html><html> <head> <title>SaaS Dashboard</title> <style> .app-wrapper { display: flex; min-height: 100vh; }
.sidebar { width: 250px; background: #1a1a1a; }
.main-content { flex: 1; padding: 2rem; transition: margin-right 200ms ease-in-out; } </style>
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", type: "sidepanel", theme: "auto", appContainerSelector: ".main-content", }); </script> </head> <body> <div class="app-wrapper"> <aside class="sidebar"> <!-- Sidebar navigation --> </aside>
<main class="main-content"> <!-- Main content - will be pushed when sidepanel opens --> <h1>Dashboard</h1> <p>Your content here...</p> </main> </div> </body></html>E-commerce with Custom Triggers
Section titled “E-commerce with Custom Triggers”Product pages with custom “Ask AI” buttons:
<!DOCTYPE html><html> <head> <title>Product Page</title> <style> .sa-button { display: none !important; } /* Hide default button */
.product-help-btn { background: #4f46e5; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 0.5rem; cursor: pointer; font-weight: 500; } </style>
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", }); </script> </head> <body> <div class="product-page"> <h1>Premium Widget</h1> <p class="price">$99.99</p>
<div class="product-description"> <p>This amazing product includes...</p> </div>
<button class="product-help-btn" onclick="SiteAssist('open')"> 💬 Ask AI about this product </button>
<button class="add-to-cart" onclick="addToCart()">Add to Cart</button> </div>
<script> function addToCart() { // Your add to cart logic here console.log("Item added to cart"); } </script> </body></html>Documentation Site with Content Selection
Section titled “Documentation Site with Content Selection”Perfect for documentation sites where you want to restrict text selection to main content areas:
<!DOCTYPE html><html> <head> <title>Documentation</title> <style> .sidebar { width: 250px; float: left; padding: 1rem; }
.main-content { margin-left: 250px; padding: 2rem; } </style>
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", contentSelector: ".main-content", // Only show popover in main content }); </script> </head> <body> <div class="sidebar"> <nav> <h3>Navigation</h3> <ul> <li><a href="/getting-started">Getting Started</a></li> <li><a href="/api-reference">API Reference</a></li> <li><a href="/examples">Examples</a></li> </ul> <!-- Text selection popover won't appear here --> </nav> </div>
<div class="main-content"> <h1>Getting Started</h1> <p> Welcome to our documentation. You can select any text in this area to ask questions about it. </p> <p> For example, select the text "API Reference" above and ask "What's in the API reference?" </p> <!-- Text selection popover WILL appear here --> </div> </body></html>E-commerce with Global Text Selection
Section titled “E-commerce with Global Text Selection”Enable text selection everywhere for comprehensive product support:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", contentSelector: false, // Show popover everywhere });</script>Blog with Article-Only Selection
Section titled “Blog with Article-Only Selection”Restrict text selection to article content only:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", contentSelector: "article .content", // Only in article content });</script>Documentation Site with Auto-Open
Section titled “Documentation Site with Auto-Open”Open widget automatically for users who seem stuck:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", });
// Track user behavior let searchAttempts = 0;
// Count search attempts document.querySelector(".search-input")?.addEventListener("input", () => { searchAttempts++;
// If user searched 3+ times, offer help if (searchAttempts >= 3 && !localStorage.getItem("help_offered")) { setTimeout(() => { SiteAssist("open"); localStorage.setItem("help_offered", "true"); }, 2000); } });
// If user stays for 60s without interaction, offer help setTimeout(() => { if (!localStorage.getItem("help_offered")) { SiteAssist("open"); localStorage.setItem("help_offered", "true"); } }, 60000);</script>Multi-Language Support
Section titled “Multi-Language Support”Sync widget theme with site language:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
// Detect user's language const userLang = navigator.language || navigator.userLanguage;
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", });
// Log language for debugging console.log("User language:", userLang);</script>A/B Testing Integration
Section titled “A/B Testing Integration”Track which widget variant performs better:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
// A/B test: floating-bubble vs sidepanel const variant = Math.random() < 0.5 ? "floating-bubble" : "sidepanel";
SiteAssist("init", { apiKey: "pk_live_abc123", type: variant, theme: "auto", ...(variant === "sidepanel" && { appContainerSelector: ".main-content", }), });
// Log which variant was shown console.log("A/B test variant:", variant);
// Log engagement window.addEventListener("sa:opened", () => { console.log("Widget opened - variant:", variant); });</script>Conditional Loading by Page
Section titled “Conditional Loading by Page”Load widget only on specific pages:
<script> // Only load on pricing and product pages const shouldLoadWidget = window.location.pathname.startsWith("/pricing") || window.location.pathname.startsWith("/products/");
if (shouldLoadWidget) { !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", }); }</script>Custom Event Integration
Section titled “Custom Event Integration”Integrate with your analytics platform:
<script> !(function (t, e, c, n, s) { if (t[s]) return; const i = (t[s] = function () { i._q.push(arguments); }); i._q = []; const o = e.createElement("script"); ((o.async = !0), (o.src = "https://cnrib24ur3hk4b49.public.blob.vercel-storage.com/widget/latest/widget.js"), e.head.appendChild(o)); })(window, document, 0, 0, "SiteAssist");
SiteAssist("init", { apiKey: "pk_live_abc123", theme: "auto", });
// Forward SiteAssist events to Google Analytics window.addEventListener("sa:opened", () => { // Send event to Google Analytics if (typeof gtag !== "undefined") { gtag("event", "chat_opened", { event_category: "engagement", event_label: "SiteAssist Widget", }); } });
window.addEventListener("sa:closed", () => { // Send event to Google Analytics if (typeof gtag !== "undefined") { gtag("event", "chat_closed", { event_category: "engagement", event_label: "SiteAssist Widget", }); } });
// Forward to Segment window.addEventListener("sa:opened", () => { if (typeof analytics !== "undefined") { analytics.track("Chat Opened", { source: "siteassist", page: window.location.pathname, }); } });</script>Next Steps
Section titled “Next Steps”- API Reference - Complete API documentation
- Advanced Features - Explore powerful capabilities
- Configuration - Customization options
Need help implementing? Contact us at support@siteassist.io