How to Add a Support Widget to a React App
Add a support widget to your React app with Cossistant in a few steps. Install the package, configure the public key, launch the widget, and customize the chat bubble when you want more control.

If you're building a React app, support usually starts as "we'll figure it out later."
Later becomes real pretty fast.
Users hit bugs. They ask onboarding questions. They want help before they churn. And suddenly you're wiring a support tool into a product that was never designed around it.
So let's keep this simple.
Here's how to add a support widget to a React app with Cossistant.
And because this is one of the first things people want to change, I'll also show you how to replace the default chat bubble with your own custom trigger.
Why this matters
For small engineering-led teams, support is part of the product.
Not a separate universe. Not a tab someone checks once a day. Part of the product.
If your users run into friction, support is where you see it first. If your widget feels bolted on, that friction gets worse.
The goal here is simple:
- add support fast
- keep the setup clean
- keep the option to customize later
What you'll build
By the end, you'll have:
- the Cossistant widget running in your React app
- the public API key configured
- styles loaded
- the default widget working
- an optional custom chat bubble trigger
1. Install the package
2. Add your public API key
Cossistant supports a few different env conventions depending on your setup.
Vite
VITE_COSSISTANT_API_KEY=pk_test_xxxxNext.js
NEXT_PUBLIC_COSSISTANT_API_KEY=pk_test_xxxxOther frameworks
COSSISTANT_API_KEY=pk_test_xxxxYou can also pass the key directly with publicKey if your setup needs it.
Use a public key only. Do not put a private key in browser code.
3. Add SupportProvider
Wrap your app at the entry point:
import React from "react";
import ReactDOM from "react-dom/client";
import { SupportProvider } from "@cossistant/react";
import App from "./App";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<SupportProvider>
<App />
</SupportProvider>
</React.StrictMode>,
);If you need to pass the key explicitly, you can:
<SupportProvider publicKey={import.meta.env.VITE_COSSISTANT_API_KEY}>4. Import styles
Tailwind v4
@import "tailwindcss";
@import "@cossistant/react/support.css";Plain CSS
import React from "react";
import ReactDOM from "react-dom/client";
import { SupportProvider } from "@cossistant/react";
import "@cossistant/react/styles.css";
import App from "./App";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<SupportProvider>
<App />
</SupportProvider>
</React.StrictMode>,
);If you're already using Tailwind v4, use the support stylesheet import. If not, plain CSS is enough.
5. Render the widget
Now render it in your app:
import { Support } from "@cossistant/react";
export default function App() {
return (
<main>
<h1>You are ready to chat</h1>
<Support />
</main>
);
}That is enough to get the default support widget on screen.
6. Identify logged-in users
If your app has auth, identify the visitor so support stays tied to the right person.
import { IdentifySupportVisitor, Support } from "@cossistant/react";
export default function App() {
const user = {
id: "user_123",
email: "jane@acme.com",
name: "Jane Doe",
};
return (
<>
<IdentifySupportVisitor
externalId={user.id}
email={user.email}
name={user.name}
/>
<Support />
</>
);
}Optional, but if you're building a SaaS, this is usually the right move.
7. Add default messages and quick options
If you want the widget to feel less blank the first time someone opens it, add some starter context.
import { Support, SupportConfig } from "@cossistant/react";
import { Support, SupportConfig } from "@cossistant/react";
import { type DefaultMessage, SenderType } from "@cossistant/types";
const user: { name: string | null } = {
name: "Jane Doe",
};
const defaultMessages: DefaultMessage[] = [
{
content: `Hi ${user.name ?? "there"}, anything I can help with?`,
senderType: SenderType.TEAM_MEMBER,
},
];
const quickOptions: string[] = ["How do I identify a visitor?"];
export default function App() {
return (
<>
<SupportConfig
defaultMessages={defaultMessages}
quickOptions={quickOptions}
/>
<Support />
</>
);
}Not required. But it makes the first interaction feel more intentional.
8. Add a custom support widget chat bubble
This is the part a lot of people care about.
The default floating trigger is useful, but most teams eventually want something that feels more like their app.
Cossistant supports a custom trigger through Support.Trigger.
That means you can replace the default chat bubble with your own button, your own label, your own layout, and your own unread badge logic.
Here's a simple custom chat bubble:
import { Support, type TriggerRenderProps } from "@cossistant/react";
export default function App() {
return (
<Support side="bottom" align="end">
<Support.Trigger className="fixed bottom-6 right-6 flex items-center gap-2 rounded-full bg-black px-4 py-3 text-sm font-medium text-white shadow-lg">
{({ isOpen, unreadCount }: TriggerRenderProps) => (
<>
<span>{isOpen ? "Close" : "Chat with us"}</span>
{unreadCount > 0 && (
<span className="rounded-full bg-white px-2 py-0.5 text-xs text-black">
{unreadCount}
</span>
)}
</>
)}
</Support.Trigger>
</Support>
);
}That already gets you most of the way there.
You can change:
- the label
- the colors
- the shape
- the position
- the unread badge treatment
If you want more control, the customization guide also supports Support.Content, Support.Root, and deeper composition patterns.
Full setup in order
Install @cossistant/react
Configure your public API key
Wrap the app with SupportProvider
Import styles
Render <Support />
Optionally identify users and add default messages
Replace the default chat bubble with Support.Trigger if you want a custom trigger
Why this setup works for React teams
The point is not just that you can get a widget running.
The point is that you can start simple and still keep control.
That matters.
A lot of support tools are fine until you want them to feel native to your product. Then you hit the wall. Weird config panels. Limited styling. No real composability.
This setup avoids that trap.
You can install it fast. Then you can shape it into your app instead of shaping your app around it.
Final thought
If you are building in React, adding support should not turn into a side quest.
Start with the default widget. Then customize the bubble when you're ready.
That is the right sequence.
If you want more control after that, keep going in the Support component guide.
Add a support widget to your React app without giving up control
Cossistant is an open-source, code-first support framework for React and Next.js. Start simple, then customize the chat bubble and the rest of the support experience when you need it.
Or sign up to get your API key and start building.
Get started free