One Widget, Every Platform
LaunchChat's chat widget is a lightweight JavaScript bundle that works on any website. The embed process is the same regardless of platform: add a config object and load the script. But each platform has its own best practices for script loading.
This guide covers the five most common platforms with copy-paste code snippets.
Prerequisites
- A LaunchChat account with a configured widget
- Your widget ID (found in Widget Settings → Embed Code)
- Access to your website's HTML or CMS
Plain HTML
The simplest integration. Add these two lines before the closing </body> tag:
<script>
window.NotionSupportConfig = { widgetId: 'your-widget-id' };
</script>
<script src="https://launchchat.dev/widget.js" defer></script>The defer attribute ensures the script loads without blocking page rendering.
With Custom Options
<script>
window.NotionSupportConfig = {
widgetId: 'your-widget-id',
position: 'bottom-right', // or 'bottom-left'
locale: 'en', // language code
};
</script>
<script src="https://launchchat.dev/widget.js" defer></script>React (Create React App, Vite)
For React apps, use a useEffect hook to load the script:
// components/ChatWidget.tsx
import { useEffect } from 'react';
export function ChatWidget({ widgetId }: { widgetId: string }) {
useEffect(() => {
// Set config
(window as any).NotionSupportConfig = { widgetId };
// Load script
const script = document.createElement('script');
script.src = 'https://launchchat.dev/widget.js';
script.defer = true;
document.body.appendChild(script);
return () => {
// Cleanup on unmount
document.body.removeChild(script);
delete (window as any).NotionSupportConfig;
};
}, [widgetId]);
return null;
}Usage in your app:
// App.tsx
import { ChatWidget } from './components/ChatWidget';
function App() {
return (
<>
{/* Your app content */}
<ChatWidget widgetId="your-widget-id" />
</>
);
}Why useEffect?
React's virtual DOM doesn't handle raw <script> tags well. Using useEffect ensures the script loads after the component mounts and cleans up when it unmounts. This prevents memory leaks in single-page applications.
Next.js (App Router)
Next.js has a built-in <Script> component optimized for third-party scripts:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script id="launchchat-config" strategy="afterInteractive">
{`window.NotionSupportConfig = { widgetId: 'your-widget-id' };`}
</Script>
<Script
src="https://launchchat.dev/widget.js"
strategy="afterInteractive"
/>
</body>
</html>
);
}Strategy Options
afterInteractive(recommended): Loads after the page is interactive. Best balance of performance and availability.lazyOnload: Loads during idle time. Slightly better performance but the widget appears later.beforeInteractive: Loads before hydration. Not recommended — the widget doesn't need to be available that early.
Next.js Pages Router
If you're using the Pages Router instead of App Router:
// pages/_app.tsx
import Script from 'next/script';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script id="launchchat-config" strategy="afterInteractive">
{`window.NotionSupportConfig = { widgetId: 'your-widget-id' };`}
</Script>
<Script
src="https://launchchat.dev/widget.js"
strategy="afterInteractive"
/>
</>
);
}WordPress
Two options for WordPress:
Option A: Theme Footer (Recommended)
- Go to Appearance → Theme File Editor
- Open
footer.php - Add before the closing
</body>tag:
<script>
window.NotionSupportConfig = { widgetId: 'your-widget-id' };
</script>
<script src="https://launchchat.dev/widget.js" defer></script>Option B: Plugin (No Code)
Use a "Header and Footer Scripts" plugin (e.g., Insert Headers and Footers by WPBeginner):
- Install and activate the plugin
- Go to Settings → Insert Headers and Footers
- Paste the embed code in the "Scripts in Footer" section
- Save
Option C: functions.php
For theme developers who prefer the WordPress way:
// functions.php
function launchchat_widget_scripts() {
wp_enqueue_script(
'launchchat-config',
'',
array(),
null,
true
);
wp_add_inline_script(
'launchchat-config',
"window.NotionSupportConfig = { widgetId: 'your-widget-id' };"
);
wp_enqueue_script(
'launchchat-widget',
'https://launchchat.dev/widget.js',
array('launchchat-config'),
null,
true
);
}
add_action('wp_enqueue_scripts', 'launchchat_widget_scripts');Webflow
Webflow supports custom code injection:
- Go to Project Settings → Custom Code
- In the "Footer Code" section, paste:
<script>
window.NotionSupportConfig = { widgetId: 'your-widget-id' };
</script>
<script src="https://launchchat.dev/widget.js" defer></script>- Save and publish
Page-Specific Widget
To show the widget only on certain pages:
- Open the page in the Webflow Designer
- Go to Page Settings → Custom Code → Before </body> tag
- Paste the embed code
- Publish
Performance Considerations
Does the Widget Slow Down My Site?
No. The widget script:
- Loads asynchronously (doesn't block rendering)
- Is ~30KB gzipped (smaller than most images)
- Initializes after the page is interactive
- Doesn't affect Core Web Vitals (LCP, FID, CLS)
Content Security Policy (CSP)
If your site uses a Content Security Policy, add these directives:
script-src 'self' https://launchchat.dev;
connect-src 'self' https://launchchat.dev;
style-src 'self' 'unsafe-inline';Subresource Integrity (SRI)
For maximum security, you can add SRI to the script tag. Contact support for the current hash.
Troubleshooting
Widget Doesn't Appear
- Check the browser console for errors
- Verify the widget ID is correct
- Ensure the script URL is
https://launchchat.dev/widget.js(not http) - Check if a Content Security Policy is blocking the script
- Verify the widget is active in your LaunchChat dashboard
Widget Appears But Doesn't Respond
- Check the browser console for API errors
- Verify your knowledge base has indexed content
- Test the widget in the LaunchChat dashboard preview first
Widget Conflicts With Other Scripts
The widget uses Shadow DOM to isolate its styles. If you experience conflicts:
- Check if another chat widget is loaded (only one should be active)
- Ensure no other script is overwriting
window.NotionSupportConfig
Advanced: Programmatic Control
The widget exposes a JavaScript API for programmatic control:
// Open the widget
window.LaunchChat?.open();
// Close the widget
window.LaunchChat?.close();
// Toggle the widget
window.LaunchChat?.toggle();This is useful for:
- Opening the widget from a custom "Help" button
- Triggering the widget based on user behavior
- Integrating with your app's navigation
Generate Your Embed Code
Don't want to write code manually? Use our Widget Code Generator to generate platform-specific embed code with your widget ID pre-filled.
Get started — embed your AI support widget on any platform.