Set up chatrelay in two minutes.
chatrelay puts a customer support chat on your website. Customer questions reach you on Telegram, WhatsApp or a web dashboard, and your replies appear on the visitor's screen instantly. This guide takes you from zero to live.
Overview
There are three pieces, and you only ever touch the first one as code:
- The widget — one
<script>tag you paste on your site. It renders the chat bubble. - Your project — created automatically when you sign up. It holds your widget id and your Telegram connection.
- Your channel — where you read and answer: Telegram, WhatsApp, or the built-in dashboard.
Everything is multi-tenant and isolated: only you ever see your visitors' conversations.
Quickstart
- Create your account
Sign up with your email and verify the 8-digit code. A project is created for you on first load — its
projectid is what goes in the embed. - Copy your embed snippet
Open the dashboard and click Embed code. Your snippet is pre-filled with your real project id and backend URL. It looks like the one below.
- Paste it on your site
Drop it just before the closing
</body>tag on any page, any stack. Reload — the chat bubble is live. - Connect a channel and reply
Pair Telegram (below) or just use the dashboard. Answer a message and watch it appear on the visitor's screen in real time.
The embed snippet
This is the entire installation. Replace your-project with the id from your dashboard. The defer attribute means it loads after your page is interactive, so it never blocks rendering.
<!-- paste once, before </body> --> <script src="https://www.chatwithdev.com/widget.js" data-chatrelay-project="your-project" data-chatrelay-convex="https://impressive-quail-820.convex.cloud" data-chatrelay-title="Chat with us" defer></script>
Installing on a specific platform? Step-by-step guides: WordPress, Shopify, Next.js, React, Webflow, Framer, Wix, Squarespace, Ghost, HTML.
Installing with an AI assistant?
If you use Cursor, Claude Code, Copilot or similar to add the widget, give it this exact instruction. It stops the assistant from “helpfully” building its own chat system, Telegram bot, or environment variables — none of which chatrelay needs.
Add the chatrelay customer support widget to this app.
1. Paste this exact script tag into the site-wide layout/HTML, right before </body>:
<script src="https://www.chatwithdev.com/widget.js"
data-chatrelay-project="YOUR_PROJECT_ID"
data-chatrelay-convex="https://impressive-quail-820.convex.cloud"
data-chatrelay-title="Chat with us" defer></script>
2. That is the ENTIRE integration. Do NOT:
- build or scaffold any chat widget, chat UI, or chat backend
- create a Telegram bot, use BotFather, or register webhooks IN THIS CODEBASE
- add any environment variables (no TELEGRAM_*, no API keys)
- install npm packages
chatrelay is fully hosted. The site owner connects their own Telegram bot inside
the chatrelay dashboard at https://www.chatwithdev.com — never in this codebase.
Optional, if the app has signed-in users — identify them so the owner can reply
by email: call window.__cr?.identify({ name, email }) after auth resolves, or add
data-chatrelay-user-name / data-chatrelay-user-email attributes to the script tag.All embed options
Configure the widget entirely from the script tag — no rebuild, no dashboard round-trip.
| Attribute | Required | What it does |
|---|---|---|
data-chatrelay-project | required | Your project id from the dashboard. Routes messages to your account. |
data-chatrelay-convex | required | Your backend URL (the .convex.cloud address). The same value for every site you own. |
data-chatrelay-accent | optional | Accent color for the visitor's bubbles and launcher highlight. Any hex, e.g. #2f53ff. |
data-chatrelay-title | optional | Header title shown at the top of the chat panel. |
data-chatrelay-subtitle | optional | Small line under the title, e.g. “Typically replies in a few minutes”. |
data-chatrelay-greeting | optional | First message a visitor sees before they've sent anything. |
data-chatrelay-user-name | optional | Name of your signed-in user, if your page knows it. Shown in your inbox instead of “Visitor”. |
data-chatrelay-user-email | optional | Email of your signed-in user. Unlocks replying by email — see Identify signed-in users. |
Connect Telegram
Visitor chats relay through a Telegram bot you own. Creating one takes about a minute at @BotFather (free), and you paste its token once in the Setup page — chatrelay handles the webhook and everything else from there.
Create your bot
- Open @BotFather
In Telegram, search for
@BotFatherand send /newbot. - Name it
Pick a display name (e.g. “Acme Support”) and a username. BotFather replies with a token like
123456789:AA… - Paste the token in Setup
In Setup, paste the token and click Connect bot. chatrelay verifies it and registers the webhook automatically.
Then pick where chats arrive. There are two modes:
Group / Topics
Each visitor becomes a separate topic (thread) in one private Telegram group. Best when conversations should stay organized or a team shares the inbox.
Direct
Every conversation arrives in your private chat with your bot. Fastest to set up; reply to a specific message to target that visitor.
Group / Topics mode
- Start pairing
After connecting your bot, Setup shows a 6-character code (it's valid for 30 minutes).
- Create a group with Topics on
In Telegram, make a new group, open its settings and enable Topics.
- Add your bot as an admin
Add your bot to the group and promote it to admin with the Manage Topics permission.
- Send your code in the group
Post the 6-character code in the group. chatrelay attaches that group to your project automatically and confirms.
Direct mode
- Open a chat with your bot
Use the tap to open link in Setup (it pre-fills your code), or start a private chat with your bot manually.
- Send your code
Send the 6-character code straight to the bot. Done — conversations now arrive in that chat.
The dashboard
Prefer a screen over a messenger? The dashboard is a full inbox — you don't need Telegram connected at all to use it.
- Inbox — every conversation with unread counts, search, and open/closed status.
- Thread — read the full transcript and reply; your reply appears on the visitor's page instantly and mirrors to Telegram if connected.
- AI assistant — draft a reply, analyze sentiment & intent, or ask a question about the conversation.
- Delivery status — if a Telegram notification can't be delivered, the message is flagged so nothing goes silently missing.
Customize the widget
Match your brand by adding the optional attributes. Here's a fully-dressed example with a green accent, custom header and greeting:
<script src="https://www.chatwithdev.com/widget.js" data-chatrelay-project="your-project" data-chatrelay-convex="https://impressive-quail-820.convex.cloud" data-chatrelay-accent="#16a34a" data-chatrelay-title="Acme Support" data-chatrelay-subtitle="We reply in minutes" data-chatrelay-greeting="Hi! Ask us anything about Acme." defer></script>
Change any value in your HTML and the widget updates on the next page load. No rebuild, no redeploy.
Identify signed-in users (premium support)
By default visitors are anonymous. If your site has accounts, you can tell the widget who is chatting — their name shows up in your inbox, the conversation is marked as premium, and you get the option to send any reply to their email as well, so they hear back even after they close the page.
There are three ways to pass the identity; use whichever fits your stack:
- Script attributes — if your page is rendered per-user, add
data-chatrelay-user-nameanddata-chatrelay-user-emailto the embed snippet. - A global, before the widget loads — set
window.chatrelayUser = { name: "Ada", email: "ada@example.com" }anywhere before the script tag runs. - At runtime — after your auth state resolves, call
window.__cr?.identify({ name, email }). Callwindow.__cr?.identify(null)on sign-out to go back to anonymous.
How it works under the hood
- Shadow DOM — the widget mounts in an isolated Shadow DOM, so your site's CSS can't leak in and the widget's can't leak out.
- Realtime by subscription — the widget subscribes to your backend; when your reply is recorded (from Telegram or the dashboard) the visitor's browser updates with no refresh and no polling.
- One backend, many sites — use the same
data-chatrelay-convexacross every site; theprojectid keeps them separate. - Privacy — each visitor gets an unguessable id in their browser's localStorage that acts as the key to their own thread. Visitors never see where you reply from.
- Lightweight — a single deferred bundle under ~30 kb, loaded after your page is interactive.
Troubleshooting
The bubble doesn't appear
Check that both data-chatrelay-project anddata-chatrelay-convex are set, and that the Convex URL is the .convex.cloud address (not.convex.site). Open your browser console for anychatrelay error.
No topic appears in my Telegram group
The bot must be an admin with Manage Topics, and Topics must be enabled on the group. Re-check the permission, then send a fresh test message from the widget.
My pairing code stopped working
Codes expire after 30 minutes. Click Get a new code in Setup to get a fresh one.
A reply didn't reach Telegram
The message is still stored and visible in the dashboard; a failed relay is flagged on the message. The most common causes are the bot losing its group permissions (re-add it as an admin) or a revoked bot token — if you regenerated the token at @BotFather, reconnect the bot in Setup with the new one.