message.comDevelopers

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 → Installation in message.com.

1. Install Wrangler

bash
npm install -g wrangler
wrangler login
wrangler deploy

2. Create a Worker project

From your terminal:

bash
mkdir message-widget-injector && cd message-widget-injector
mkdir src && touch src/worker.js wrangler.toml

3. Configure wrangler.toml

Set the route to the zone where you want the widget injected. Adjust example.com to your domain.

wrangler.toml
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
// 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

bash
wrangler deploy

Wrangler prints the deployed worker name and any errors. The route activates immediately.

6. Verify

  1. Open your site in a private window.
  2. The launcher appears in the bottom-right within two seconds.
  3. Right-click → View Page Source. Confirm the snippet is in the HTML.
  4. 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-type for text/html before 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.com serves HTML and cdn.example.com serves assets, set the route only on the HTML hostname.

Next steps