Install live chat via Cloudflare Workers
Inject the widget on every HTML response without touching origin code. Useful for legacy CMSs, static sites you cannot easily edit, or multi-tenant deploys where you want a single source of truth for the install. Roughly 15 minutes if you have never used Wrangler.
A one-click Cloudflare install is on our roadmap: OAuth to your Cloudflare account, we provision the Worker for you. Until that ships, this manual install is the equivalent. See Cloudflare 1-click.
Before you begin
- A Cloudflare account with the zone you want to inject on already added.
- Workers enabled on your account (free plan includes 100k requests/day).
- Your install snippet from
Settings → Chats → Installationin message.com.
1. Install Wrangler
npm install -g wrangler
wrangler login
wrangler deploy2. Create a Worker project
From your terminal:
mkdir message-widget-injector && cd message-widget-injector
mkdir src && touch src/worker.js wrangler.toml3. Configure wrangler.toml
Set the route to the zone where you want the widget injected. Adjust example.com to your domain.
name = "message-widget-injector"
main = "src/worker.js"
compatibility_date = "2025-01-01"
routes = [
{ pattern = "example.com/*", zone_name = "example.com" }
]4. Write the Worker
This Worker uses Cloudflare's HTMLRewriter to append the snippet to the closing </body> tag on every HTML response. Non-HTML responses pass through untouched.
// src/worker.js
const SNIPPET = `
<script>
(function(d,s,o){
var j=d.createElement(s);j.async=1;j.src='https://app.message.com/widget.js';
j.dataset.workspace=o;
d.head.appendChild(j);
})(document,'script','YOUR_WORKSPACE_ID');
</script>
`;
class BodyInjector {
element(el) {
el.append(SNIPPET, { html: true });
}
}
export default {
async fetch(request) {
const response = await fetch(request);
const ct = response.headers.get("content-type") || "";
if (!ct.includes("text/html")) return response;
return new HTMLRewriter()
.on("body", new BodyInjector())
.transform(response);
},
};Replace YOUR_WORKSPACE_ID with your workspace ID.
5. Deploy
wrangler deployWrangler prints the deployed worker name and any errors. The route activates immediately.
6. Verify
- Open your site in a private window.
- The launcher appears in the bottom-right within two seconds.
- Right-click → View Page Source. Confirm the snippet is in the HTML.
- Send a test message. The conversation lands in
app.message.com.
Common pitfalls
- Origin already injects the snippet. If the Worker plus the origin both inject, you get two scripts. The widget tolerates this (second load is ignored), but it wastes bytes. Pick one source of truth.
- HTMLRewriter cost. Streamed transforms are cheap. Most Workers using this pattern run well within the free 10ms CPU budget per request.
- Content-Type sniffing. The Worker checks
content-typefortext/htmlbefore rewriting. Origin responses that omit the header (rare) are skipped. - Edge cache invalidation. Cloudflare caches HTML responses if your origin lets it. After deploying the Worker, purge the zone's cache or wait for TTL.
- Static assets behind a separate hostname. If
www.example.comserves HTML andcdn.example.comserves assets, set the route only on the HTML hostname.