Embedding
Add an AI chat widget to any website with a single script tag. The widget connects to your REPLR and lets visitors chat directly on your site — no backend required.
Overview
The REPLR embed widget is a lightweight script that renders a chat interface on your website. It handles the connection to your REPLR, manages conversation state, and provides a polished UI out of the box. Visitors can start chatting immediately without creating an account.
One line of code
Drop a single script tag into your HTML and the widget appears automatically.
Fully customizable
Control theme, position, colors, dimensions, and greeting via data attributes.
JavaScript API
Programmatically open, close, send messages, and listen to events.
Quick Start
Add this script tag to the <body> of any HTML page. Replace YOUR_REPLR_ID with your REPLR's ID from the dashboard.
<script src="https://replr.ai/embed.js" data-replr-id="YOUR_REPLR_ID"></script>That's it. A chat button will appear in the bottom-right corner of your page. Clicking it opens a full chat interface connected to your REPLR.
Configuration Options
All configuration is done via data-* attributes on the script tag. No JavaScript configuration object required.
| Attribute | Default | Description |
|---|---|---|
data-replr-idrequired | — | Required. Your REPLR's unique ID. |
data-theme | "auto" | "light", "dark", or "auto" (matches your site's color scheme). |
data-position | "bottom-right" | "bottom-right" or "bottom-left". |
data-primary-color | — | Hex color for the widget button and header (e.g. "#8b5cf6"). |
data-greeting | — | Custom greeting message shown when the widget opens. |
data-width | 380 | Widget width in pixels. |
data-height | 600 | Widget height in pixels. |
data-open | "false" | "true" to open the widget automatically on page load. |
data-hide-branding | "false" | "true" to remove REPLR branding (Pro+ plan required). |
Full example
<script
src="https://replr.ai/embed.js"
data-replr-id="rpl_x4y5z6a7b8c9"
data-theme="dark"
data-position="bottom-right"
data-primary-color="#8b5cf6"
data-greeting="Hey! How can I help you today?"
data-width="400"
data-height="640"
data-open="false"
data-hide-branding="false"
></script>JavaScript API
After the embed script loads, a global window.REPLR object is available with the following methods.
| Method | Description |
|---|---|
REPLR.open() | Open the chat widget. |
REPLR.close() | Close the chat widget. |
REPLR.toggle() | Toggle the widget open or closed. |
REPLR.sendMessage(text) | Programmatically send a message as the visitor. |
REPLR.on(event, callback) | Subscribe to widget events. See Events below. |
// Open the widget when a custom button is clicked
document.getElementById("help-btn").addEventListener("click", () => {
REPLR.open();
});
// Send a contextual message based on the current page
REPLR.sendMessage("I have a question about " + document.title);Events
Use REPLR.on(event, callback) to listen for widget lifecycle and messaging events.
| Event | Payload | Description |
|---|---|---|
ready | — | Widget has loaded and is ready to use. |
open | — | Chat widget was opened. |
close | — | Chat widget was closed. |
message | { role, content } | A new message was sent or received. role is "user" or "assistant". |
error | { code, message } | An error occurred (network failure, rate limit, etc.). |
REPLR.on("ready", () => {
console.log("Widget loaded");
});
REPLR.on("message", (data) => {
console.log(`[${data.role}]: ${data.content}`);
// Track messages in your analytics
analytics.track("replr_message", {
role: data.role,
length: data.content.length,
});
});
REPLR.on("error", (err) => {
console.error("REPLR error:", err.code, err.message);
});Styling
Beyond data attributes, you can fine-tune the widget appearance using CSS custom properties. Add these to your stylesheet to override defaults.
| Property | Default | Description |
|---|---|---|
--replr-font | system-ui | Font family used in the widget. |
--replr-radius | 12px | Border radius for the widget container and messages. |
--replr-z-index | 9999 | Stack order of the widget overlay. |
:root {
--replr-font: "Inter", sans-serif;
--replr-radius: 16px;
--replr-z-index: 50000;
}React / Next.js Integration
In React or Next.js projects, wrap the embed script in a component so it loads cleanly within the component lifecycle. The example below works with both the Pages Router and the App Router.
"use client";
import { useEffect, useRef } from "react";
interface ReplrWidgetProps {
replrId: string;
theme?: "light" | "dark" | "auto";
position?: "bottom-right" | "bottom-left";
primaryColor?: string;
greeting?: string;
width?: number;
height?: number;
open?: boolean;
hideBranding?: boolean;
}
export function ReplrWidget({
replrId,
theme = "auto",
position = "bottom-right",
primaryColor,
greeting,
width,
height,
open,
hideBranding,
}: ReplrWidgetProps) {
const loaded = useRef(false);
useEffect(() => {
if (loaded.current) return;
loaded.current = true;
const script = document.createElement("script");
script.src = "https://replr.ai/embed.js";
script.async = true;
script.dataset.replrId = replrId;
script.dataset.theme = theme;
script.dataset.position = position;
if (primaryColor) script.dataset.primaryColor = primaryColor;
if (greeting) script.dataset.greeting = greeting;
if (width) script.dataset.width = String(width);
if (height) script.dataset.height = String(height);
if (open) script.dataset.open = "true";
if (hideBranding) script.dataset.hideBranding = "true";
document.body.appendChild(script);
return () => {
script.remove();
};
}, [replrId, theme, position, primaryColor, greeting, width, height, open, hideBranding]);
return null;
}Examples
Copy-paste examples for common use cases.
Basic — Bottom-right chat bubble
<!DOCTYPE html>
<html>
<head><title>My Site</title></head>
<body>
<h1>Welcome to my site</h1>
<!-- REPLR embed widget -->
<script
src="https://replr.ai/embed.js"
data-replr-id="YOUR_REPLR_ID"
></script>
</body>
</html>Custom theme, position & greeting
<script
src="https://replr.ai/embed.js"
data-replr-id="YOUR_REPLR_ID"
data-theme="dark"
data-position="bottom-left"
data-accent-color="#8B5CF6"
data-greeting="Hey! Ask me anything about our product."
data-width="400"
data-height="600"
></script>JavaScript API — Open on button click
<button id="chat-btn">Talk to our AI</button>
<script src="https://replr.ai/embed.js" data-replr-id="YOUR_REPLR_ID"></script>
<script>
document.getElementById('chat-btn').addEventListener('click', () => {
window.ReplrEmbed.open();
});
</script>React / Next.js integration
// components/ReplrChat.jsx
'use client';
import { useEffect } from 'react';
export function ReplrChat({ replrId }) {
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://replr.ai/embed.js';
script.dataset.replrId = replrId;
script.dataset.theme = 'dark';
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
// Clean up widget
window.ReplrEmbed?.destroy();
};
}, [replrId]);
return null;
}Custom styling with CSS variables
:root {
--replr-primary: #8B5CF6;
--replr-bg: #0A0A0A;
--replr-text: #E5E5E5;
--replr-border: rgba(255, 255, 255, 0.05);
--replr-radius: 16px;
--replr-font: 'Inter', system-ui, sans-serif;
}
/* Hide the default fab button */
.replr-fab { display: none; }
/* Custom chat window sizing */
.replr-chat {
max-height: 80vh;
border-radius: var(--replr-radius);
}Security
- •Public settings only. The widget uses your REPLR's public configuration. Your API keys and system prompt are never exposed to the browser.
- •Anonymous by default. Conversations are stored server-side but are anonymous unless the visitor authenticates through your application.
- •Domain allowlisting. In the dashboard, you can restrict which domains are allowed to load your widget. Requests from unlisted domains will be rejected.
- •Rate limiting. The embed endpoint enforces per-IP rate limits to prevent abuse. Excessive requests will return a 429 status.
- •HTTPS required. The embed script and all widget API calls are served exclusively over TLS.