npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agentiachat/react

v0.5.1

Published

Embeddable Agentia chat widget for React — streaming AI chat with theming, floating launcher, and admin-driven settings

Downloads

82

Readme

@agentiachat/react

Embeddable Agentia chat widget for React — streaming AI chat with a floating launcher, full theming, and admin-driven settings. See the docs for guides and the full API reference.

  • Zero runtime dependencies — only react / react-dom as peers (18 or 19)
  • Streaming responses via Server-Sent Events
  • Style-isolated — renders in a shadow root, so host-page CSS can't break it (and its styles can't leak out); no CSS import needed
  • SSR-safe — works in Next.js (Pages and App Router) without next/dynamic
  • Themeable — CSS custom properties (they pierce the shadow boundary) and ::part() hooks, plus dark mode and admin-configured appearance
  • Headless option — use the useChat hook with your own UI
  • ESM + CJS builds with full TypeScript types

Install

npm i @agentiachat/react
# peer deps: react@^18||^19, react-dom@^18||^19

Quick start

import { ChatProvider, FloatingChat } from '@agentiachat/react';
// No CSS import needed — styles are injected into the widget's shadow root.

export function App() {
  return (
    <>
      {/* your app */}
      <ChatProvider chatId="YOUR_PUBLIC_CHAT_ID">
        <FloatingChat />
      </ChatProvider>
    </>
  );
}

Note: apiUrl defaults to the hosted Agentia API (https://api.agentia.chat/api), so embedding a chat hosted on Agentia needs only chatId. Self-hosters pass apiUrl pointing at their own deployment — it must include the API's global prefix (/api by default), since the widget calls {apiUrl}/public/... endpoints.

Use Chat instead of FloatingChat to render the conversation inline:

<ChatProvider chatId="YOUR_PUBLIC_CHAT_ID">
  <Chat title="Support" />
</ChatProvider>

Components

ChatProvider

Wraps any chat UI and manages conversations, streaming, and visitor identity.

| Prop | Type | Default | Description | | ----------- | -------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | chatId | string | — (required) | Public chat ID from your Agentia admin | | apiUrl | string | https://api.agentia.chat/api | Agentia API base URL including the global prefix. Defaults to the hosted API; set it only when self-hosting. | | visitorId | string | auto-generated | Stable visitor ID (persisted in localStorage if omitted) |

Chat

Full conversation UI (messages, composer, streaming indicator).

| Prop | Type | Default | Description | | --------------- | ------------------------ | ------------- | --------------------------------------------------- | | title | string | admin setting | Header title override | | subtitle | string | admin setting | Header subtitle override | | placeholder | string | admin setting | Composer placeholder (supports {variable} tokens) | | variables | Record<string, string> | {} | Values for {variable} tokens in UI copy | | showPoweredBy | boolean | true | "Powered by Agentia" footer | | className | string | — | Extra class on the root element |

FloatingChat

Chat wrapped in a floating launcher button (popover / drawer / fullscreen — driven by the chat's admin widget settings, including corner position).

Accepts all Chat props plus:

| Prop | Type | Default | Description | | ------------- | --------- | ------- | ------------------------- | | defaultOpen | boolean | false | Start with the panel open |

Headless usage

import { ChatProvider, useChat } from '@agentiachat/react';

function MyChatUi() {
  const { messages, sendMessage, isThinking, isStreaming, streamingContent } = useChat();
  // render your own UI
}

<ChatProvider chatId="..." apiUrl="...">
  <MyChatUi />
</ChatProvider>;

A/B experiments

When an experiment is running on a chat, the widget sends its visitorId with the bootstrap request and renders the visitor's assigned variant. The assignment is exposed as meta on the context ({ versionId, experimentId, variantId, variantKey }) for your own analytics.

Versions of this package older than 0.5.0 don't send a visitorId at bootstrap: visitors still bucket into variant flows when they chat, but they all see the control styling. Upgrade before running experiments that change appearance or copy; flow/persona/provider experiments work on any version.

Theming & style isolation

The widget renders inside a shadow root, so the embedding page's CSS (resets, Tailwind preflight, component frameworks) can't reach in and break it, and the widget's own styles can't leak out. No CSS import is required — the stylesheet is injected automatically.

Theme it with CSS custom properties, which inherit across the shadow boundary. Set them on the widget's host element, .agentia-chat-host:

.agentia-chat-host {
  --agentia-primary: #6d28d9;
  --agentia-primary-hover: #5b21b6;
  --agentia-radius: 12px;
  --agentia-font-family: 'Inter', sans-serif;
}

Available tokens: --agentia-primary, --agentia-primary-hover, --agentia-primary-text, --agentia-bg, --agentia-surface, --agentia-text, --agentia-text-muted, --agentia-border, --agentia-header-bg, --agentia-header-text, --agentia-input-bg, --agentia-input-border, --agentia-user-bubble-bg, --agentia-user-bubble-text, --agentia-assistant-bubble-bg, --agentia-assistant-bubble-text, --agentia-launcher-bg, --agentia-launcher-text, --agentia-launcher-shadow, --agentia-launcher-ring, --agentia-font-family, --agentia-font-size, --agentia-radius, --agentia-radius-sm, --agentia-shadow.

For deeper, structural overrides, target the exposed ::part() hooks from the host page:

.agentia-chat-host::part(launcher) {
  border-radius: 12px;
}
.agentia-chat-host::part(header) {
  background: #111827;
}
.agentia-chat-host::part(bubble-user) {
  background: #6d28d9;
}

Exposed parts: launcher, panel, close, header, avatar, title, subtitle, messages, message, message-user, message-assistant, bubble, bubble-user, bubble-assistant, timestamp, composer, input, send-button, welcome, greeting, prompt, powered.

Dark mode and full appearance can also be configured in the Agentia admin (settings are fetched at runtime).

Server-side rendering

The package guards all browser APIs (window, localStorage, EventSource). The widget mounts into its shadow root on the client after hydration, so it renders nothing on the server — safe for SSR / Next.js without next/dynamic (and the chat isn't indexed as page content).

Embedding origins

No CORS setup is required to embed against the hosted Agentia API — it accepts the widget's requests from any origin out of the box. Visitors are identified by a visitorId (persisted in localStorage), not cookies, so there's nothing to configure on the embedding site.

To restrict which sites may embed a chat, set an allowed origins list in the chat's security settings (Agentia admin). When the list is empty (the default), any origin is allowed; when it's non-empty, only the listed origins can load the widget and others are blocked by the browser. This is a browser-level embedding control (and cost hygiene), not a hard security boundary — request volume is bounded by per-chat rate limits.

Self-hosting: the public chat API applies this per-workspace allowlist automatically. The server-wide ALLOWED_ORIGINS env var only governs the admin API, not the embeddable /public/* widget endpoints.

License

MIT