Set up chatwithdev in two minutes.
chatwithdev puts a customer support chat on your website. Customer questions reach you on Telegram 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, 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 chatwithdev needs.
Add the chatwithdev 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
chatwithdev is fully hosted. The site owner connects their own Telegram bot inside
the chatwithdev 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-preset | optional | Who answers: dev, ceo, support, sales or feedback. Sets a matching title, greeting and accent (your explicit attributes above always win), and frames the Telegram ticket button to fit. A preset chosen in the dashboard's Embed modal overrides this attribute — switch products without touching your site. |
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. You don't create it by hand: one tap in Setup and chatwithdev creates the bot for you inside Telegram, then configures its webhook, description and commands automatically.
Create your bot
- Tap “Create my bot”
In Setup, tap the button (or scan the QR code to continue on your phone). Telegram opens on a chat with our setup bot.
- Confirm in Telegram
Tap Create my bot there — the name and username are pre-filled. Telegram hands the new bot straight to chatwithdev, which configures it within a second.
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
Right after your bot exists it asks where chats should go, and 👥 A team group is one of the two buttons. Tap it and pick a group — the bot joins and connects itself.
- No group yet? Make one
In Telegram: menu → New Group, add a teammate, name it. Then add your bot to it — it pairs itself the moment it joins, with nothing to copy.
- Optional: one thread per visitor
Open the group's settings and enable Topics, then add the bot as an admin with Manage Topics. Every visitor then gets their own thread.
/ stay in the group — use // for notes to your team.Direct mode (the default)
Every conversation arrives in your private chat with your bot — one tap in Setup, nothing else. Two commands make it do everything a group used to:
/invite— hands you a link. Whoever opens it gets the same visitor chats in their own Telegram and can answer from there. No group, no admin rights, and they can/leavewhenever they want. Everyone sees who answered what, so nobody replies twice./threads— one topic per visitor, inside your own chat with the bot. It needs a single toggle in the @BotFather app: tap Open, pick your bot, Bot Settings → Threads Settings → Threaded Mode. (It is not in the/mybotskeyboard.) The command walks you through it, and threading switches on by itself once it's set.
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.
Personas
A persona decides who the widget says is answering — its title, greeting, accent and the Telegram ticket label. Pick it in the dashboard's Embed code panel under Who answers?; your site updates on the next load, no snippet change.
One voice
Choose one of Developer, Founder, Support, Sales or Ideas. Picking another replaces it.
Several, in one bubble
Enable up to five. The widget shows a chooser strip — the visitor picks who they want to reach, still one bubble on your site. Their pick is remembered.
Visitor a1b2c3 · Founder, the ticket button follows that persona, the dashboard tags the conversation, and AI drafts answer in that voice. One script tag always means one bubble — a second tag on the same page is ignored.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.
- Deferred loading — a small loader fetches the chat code when the page is idle or a visitor first interacts. The widget keeps its styles separate from your page.
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 anychatwithdev 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.
The connect buttons stopped working
The links behind them expire after 30 minutes. Reload Setup — it arms fresh ones automatically.
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 bot that was deleted in Telegram — in that case remove it in Setup and create a new one with one tap.
