From 5c1fe2c6afc38327eac83515e8d9cc92b769fee8 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 4 Nov 2025 18:12:57 +0530 Subject: [PATCH] feat: add chatwoot integration (#39) --- ui/Dockerfile | 2 + ui/src/app/layout.tsx | 2 + ui/src/components/ChatwootWidget.tsx | 78 ++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 ui/src/components/ChatwootWidget.tsx diff --git a/ui/Dockerfile b/ui/Dockerfile index 6964512..be8fda3 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -34,6 +34,8 @@ ENV NEXT_PUBLIC_DEPLOYMENT_MODE="oss" ENV NEXT_PUBLIC_BACKEND_URL="http://localhost:8000" ENV BACKEND_URL="http://api:8000" ENV NEXT_TELEMETRY_DISABLED="1" +ENV NEXT_PUBLIC_CHATWOOT_URL="https://chat.dograh.com" +ENV NEXT_PUBLIC_CHATWOOT_TOKEN="3fkFx2mCEjNHjM9gaNc4A82X" # Build the application with standalone mode RUN npm run build && \ diff --git a/ui/src/app/layout.tsx b/ui/src/app/layout.tsx index 17080fa..d9e5820 100644 --- a/ui/src/app/layout.tsx +++ b/ui/src/app/layout.tsx @@ -4,6 +4,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import { Suspense } from "react"; +import ChatwootWidget from "@/components/ChatwootWidget"; import PostHogIdentify from "@/components/PostHogIdentify"; import SpinLoader from "@/components/SpinLoader"; import { Toaster } from "@/components/ui/sonner"; @@ -44,6 +45,7 @@ export default function RootLayout({ {children} + diff --git a/ui/src/components/ChatwootWidget.tsx b/ui/src/components/ChatwootWidget.tsx new file mode 100644 index 0000000..1fd558d --- /dev/null +++ b/ui/src/components/ChatwootWidget.tsx @@ -0,0 +1,78 @@ +"use client"; + +import { useEffect } from "react"; + +declare global { + interface Window { + chatwootSDK?: { + run: (config: { + websiteToken: string; + baseUrl: string; + }) => void; + }; + chatwootSettings?: { + position?: "left" | "right"; + type?: "standard" | "expanded_bubble"; + launcherTitle?: string; + }; + } +} + +const CHATWOOT_BASE_URL = process.env.NEXT_PUBLIC_CHATWOOT_URL; +const CHATWOOT_WEBSITE_TOKEN = process.env.NEXT_PUBLIC_CHATWOOT_TOKEN; + +export default function ChatwootWidget() { + useEffect(() => { + // Don't initialize if environment variables are not set + if (!CHATWOOT_BASE_URL || !CHATWOOT_WEBSITE_TOKEN) { + console.warn("Chatwoot not configured: Missing NEXT_PUBLIC_CHATWOOT_URL or NEXT_PUBLIC_CHATWOOT_TOKEN"); + return; + } + + // Prevent duplicate initialization + if (window.chatwootSettings) { + return; + } + + // Configure Chatwoot widget settings + window.chatwootSettings = { + position: "right", + type: "standard", + launcherTitle: "Chat with us", + }; + + // Check if script is already loaded + const existingScript = document.querySelector( + `script[src="${CHATWOOT_BASE_URL}/packs/js/sdk.js"]` + ); + + if (existingScript) { + // Script already exists, just initialize if SDK is available + if (window.chatwootSDK) { + window.chatwootSDK.run({ + websiteToken: CHATWOOT_WEBSITE_TOKEN, + baseUrl: CHATWOOT_BASE_URL, + }); + } + return; + } + + // Create and inject the Chatwoot SDK script + const script = document.createElement("script"); + script.src = `${CHATWOOT_BASE_URL}/packs/js/sdk.js`; + script.async = true; + script.defer = true; + script.onload = () => { + if (window.chatwootSDK) { + window.chatwootSDK.run({ + websiteToken: CHATWOOT_WEBSITE_TOKEN, + baseUrl: CHATWOOT_BASE_URL, + }); + } + }; + + document.body.appendChild(script); + }, []); + + return null; +}