USE CASE

Vite and React AI support chat widget

Add Deacon to a Vite and React app with one line in index.html. It answers visitors from your docs and says so when it doesn’t know.

By the Deacon team

Published

Deacon is an AI support chat for a React app built with Vite, and it goes in as a single line of index.html, with no npm package and no React component. It answers people from your docs and pages within seconds. Asked something those don’t cover, it admits it doesn’t know and offers a box for an email address, or a one-tap reply once your app passes Deacon the logged-in user. Leaving an address sends you an email with the question, unless you already have the dashboard open, and what you write back appears in their chat. The free plan comes with 50 answers a month, no card and no end date.

This covers React apps you built with Vite yourself and ones exported from Lovable or Bolt. We read Vite’s documentation on 25 October 2026, when 8.3 was current. A coding agent can read this page as Markdown.

Two things to sort out first

Your key comes from a Deacon account. Sign up for Deacon and take it from the snippet on Install, where it’s the pk_ value of data-key. And the address the app is served from must be on Install’s list. The one you signed up with is there, with its subdomains, but a free Lovable or Bolt project publishes on an address of its own, such as a lovable.app or bolt.host one, and that needs adding. There’s nothing to install.

Install opens on Lovable’s or Bolt’s own steps when it recognises the builder, with a prompt for that builder’s chat. For an app you work on in your own editor, choose My own code. Its Copy the prompt is for Claude Code, Cursor or Codex, and the agent adds the code and checks it’s live.

index.html, the page every route starts from

Vite’s guide keeps index.html “front-and-central” at the project root, and says that in development it “is the entry point to your application”. So a tag placed there is on every route. Add Deacon’s as the last line before </body>, under your app’s own module script. That one line is the whole change.

<!-- index.html, at the project root -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Your app</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
    <script src="https://heydeacon.com/widget/v1/loader.js" data-key="pk_your_widget_key" async></script>
  </body>
</html>

Vite’s features guide lists what it bundles from this file, such as <script type="module" src>, and a classic script with a full address isn’t on that list. We checked on 25 October 2026 by building a Vite 8 project with this file, and the Deacon line came out of vite build byte for byte.

Dev server, then preview build

Vite serves development and the preview build on different ports, 5173 and 4173 by default. Install’s one-click add lists the address with the port it found, so either type localhost under Your sites on Install, which covers every port, or add localhost:4173 too when Install names it.

  1. npm run dev, then open http://localhost:5173. No button yet. Localhost isn’t listed, so the script hides itself. Install notices and shows “Found the code on localhost:5173”, with a one-click add.
  2. Refresh. Deacon’s button, Help unless you renamed it, is now in the corner.
  3. Ask a question your docs answer. Nothing asked on localhost is counted.
  4. npm run build and npm run preview, then open the preview on port 4173 and look again. This is the index.html your host will serve.

Once it’s published, Install shows the app’s domain as Live and when Deacon was last seen. On the live app, client-side routing, such as React Router’s, moves between screens without reloading index.html, so the script loads once a visit and counts each new screen as a page view.

For an agent, there’s an answer without a browser. latest says which address last loaded Deacon, and refused names a development address it wouldn’t run on. Deacon’s install guide has the rest.

curl -s "https://heydeacon.com/api/widget/seen?k=pk_your_widget_key"

Built in Lovable or Bolt

Lovable’s FAQ says its apps made before 13 May 2026 are React and Vite, and newer ones use TanStack Start. Whichever yours is, pasting the snippet into the Lovable chat and asking it to place the tag is quickest, as Deacon and Lovable explains.

Bolt, its supported technologies page says, takes any JavaScript framework that runs in the browser. When your project has index.html at its root, edit it in Code view or ask Bolt to, as Deacon and Bolt shows.

Supabase logins

When people log in to your app, pass Deacon who they are, so their name shows on the conversation and a question Deacon can’t answer gets a reply to their email in one tap. Deacon uses these details as a label only. It doesn’t check them, and the AI never sees them.

A single-page app learns about logins after it has loaded, so pass them from the listener that hears them. With Supabase, which both Lovable and Bolt can connect to, that’s onAuthStateChange, safe to use “without an async function as callback”, by its reference. Add this beside your Supabase client, in the file that creates it.

// beside createClient(), such as in src/lib/supabase.ts
supabase.auth.onAuthStateChange((_event, session) => {
  const user = session?.user;

  window.deaconUser = user
    ? { id: user.id, email: user.email, name: user.user_metadata?.full_name }
    : null;
  window.Deacon?.identify(window.deaconUser);
});

declare global {
  interface Window {
    deaconUser?: { id?: string | number; email?: string; name?: string } | null;
    Deacon?: {
      identify(user: { id?: string | number; email?: string; name?: string } | null): void;
      open(): void;
    };
  }
}

The callback can fire before or after Deacon’s script runs, and setting the variable as well as calling identify covers both. A null after someone logs out makes the next person on that computer a new visitor. If the name lives somewhere other than full_name in your user metadata, read it from there. To check it, log in on localhost and open any screen, and Install’s “Do your users log in?” card says when it has seen you.

What you learn from the chat

Visitors get an answer without leaving the screen they’re stuck on. You get the other half. Each question your docs missed sits in the dashboard with an Answer this button, and Topics groups what people ask and counts the people behind each topic. Bug reports land next to the JavaScript errors your app throws for them, and each copies for your coding agent in one click.

Vite and React questions

I pasted the tag and see no chat button. Why?

Your browser’s console will have a [Deacon] line saying why. “isn’t in your allowed domains” is the usual one on a builder, where the published lovable.app or bolt.host address, or a preview, isn’t on Install’s list. “Unknown widget key” means the data-key isn’t yours, and “could not start” is followed by the error that stopped it. No [Deacon] line at all usually means the build you’re looking at predates the change, so rebuild and hard-refresh, or that the button is hidden in Appearance. If the button is there but the chat opens blank, a line saying the chat frame “did not load” points to a Content Security Policy without https://heydeacon.com in frame-src.

Is there a React component for Deacon?

No, and you don’t need one. The tag in index.html is the whole install. If something also loads the script a second time, Deacon notices it’s already running and ignores the copy.

How do I open the chat from my own button?

Hide Deacon’s button in Appearance, then call window.Deacon?.open() in your button’s click handler. The declaration above types it.

Try it on your own documentation

Add your help pages, ask it the question you know your docs cannot answer, and watch it say so.

The free plan covers 50 answers a month on one seat, and the paid plans are on the pricing page.

Start free

Free plan, no card.

READ NEXT

  • Deacon and Lovable

    Lovable counts your visitors on its own. Deacon adds goals, funnels, JavaScript errors and an AI agent that answers them, from one script tag and a free plan.

  • Deacon and Bolt

    Bolt can build a chatbot, but you add the API key and pay for every reply. Deacon answers from your docs, says when it doesn’t know, and goes in with one line.

  • What to do in the week after launching a website

    The checks to run before you post the link, the four numbers worth watching on launch day and what to do with the questions your first visitors send.