Overview

This guide provides complete, real-world examples of integrating the SiteAssist widget in various scenarios and platforms.

Basic Examples

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

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:

# .env.local
NEXT_PUBLIC_SITEASSIST_PUBLISHABLE_KEY=pk_live_abc123

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>
    </>
  );
}

React

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

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

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

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

<?php
function 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

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

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

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

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

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

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

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

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

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

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

Need help implementing? Contact us at support@siteassist.io