c.l.cladDocs

Framework recipes

Copy-paste integration recipes for React, Next.js (App Router), and Vue 3.

React

Include the Quickstart <script> snippet once in your app shell, then use a small hook to identify the user on login and shut down on logout. Calls made before the widget finishes loading are queued and replayed, so you don't need to wait for it to be ready.

import { useEffect } from "react";
 
export function useSupportChat(user) {
  useEffect(() => {
    if (user) {
      SupportChat("identify", {
        user,
        tokenProvider: () =>
          fetch("/api/support-chat-token").then((r) => r.text()),
      });
    } else {
      SupportChat("shutdown", { clearStorage: true });
    }
  }, [user?.id]);
}

Next.js (App Router)

Load the widget with next/script and render it once in your root layout:

"use client";
import Script from "next/script";
 
export default function SupportChatLoader() {
  return (
    <Script id="support-chat" strategy="afterInteractive">
      {`
        window.SupportChatSettings = { workspaceId: "{YOUR_WORKSPACE_ID}", widgetId: "{YOUR_WIDGET_ID}" };
        (function (w, d) {
          w.SupportChat = w.SupportChat || function () {
            (w.SupportChat.q = w.SupportChat.q || []).push(arguments);
          };
          var s = d.createElement("script");
          s.async = true;
          s.src = "https://clad-server-staging.up.railway.app/widget/v1/widget.js";
          d.head.appendChild(s);
        })(window, document);
      `}
    </Script>
  );
}

Vue 3

With the Quickstart <script> snippet included once in your index.html, drive the widget from your components:

import { onMounted } from "vue";
 
export function useSupportChat(user) {
  onMounted(() => {
    if (user) {
      SupportChat("identify", {
        user,
        tokenProvider: () =>
          fetch("/api/support-chat-token").then((r) => r.text()),
      });
    }
  });
}