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

@nickle-ai/chatbot-react

v0.1.9

Published

Customizable chatbot bubble + widget for React websites

Readme

@nickle-ai/chatbot-react

Customizable chatbot bubble + chat panel for React apps.

Install (npm)

npm install @nickle-ai/chatbot-react

Do not install from github:schvffler/chatbot-react. That installs monorepo source and internal playground files.

Quick Start

import { ChatbotProvider, ChatbotWidget } from "@nickle-ai/chatbot-react";

export function SiteChat() {
  return (
    <ChatbotProvider
      webhookUrl={process.env.NEXT_PUBLIC_CHATBOT_WEBHOOK_URL || ""}
      localeTexts={{
        en: { inputPlaceholder: "Ask something..." },
        de: { inputPlaceholder: "Frag etwas..." },
      }}
    >
      <ChatbotWidget />
    </ChatbotProvider>
  );
}

The package loads default widget styles automatically. Import @nickle-ai/chatbot-react/styles.css only if you want explicit CSS import control.

How It Works

Provider runtime

ChatbotProvider manages:

  • session id and chat history in sessionStorage
  • locale-aware copy for agentName, assistantNote, welcomeMessage, disclaimer, and input placeholder
  • delayed welcome message when opened with an empty conversation
  • merged global config + latest ChatbotPageConfig override

Locale resolution order (when locale prop is not set):

  1. URL first path segment if it matches a supported locale (for example /de, /fr)
  2. document.documentElement.lang
  3. browser language (navigator.language)

You can override locale copy per language with localeTexts.

Default styling is deterministic and does not inherit host-site CSS variables. Visual changes happen only when you pass explicit widget overrides (for example theme, icons, or classNames).

Send/receive flow

When sendMessage is called, the widget:

  1. Appends the user message.
  2. Adds a streaming assistant placeholder.
  3. Builds the request via adapter (buildRequest).
  4. Sends webhook payload including metadata (sessionId, pageUrl, locale, agentName, history).
  5. Parses non-streaming or streaming response and updates assistant message state.

Streaming behavior

streamingMode options:

  • auto: stream when response looks stream-compatible
  • on: force stream parsing
  • off: parse as non-streaming response

Stream formats supported:

  • text/event-stream (SSE)
  • line-delimited JSON/text
  • application/x-ndjson

Webhook Contract

Request payload (JSON mode)

{
  "message": "User message text",
  "sessionId": "uuid-or-generated-id",
  "metadata": {
    "sessionId": "...",
    "pageUrl": "https://client-site/path",
    "timestamp": "2026-03-02T18:00:00.000Z",
    "agentName": "Assistant",
    "locale": "en",
    "history": [
      {
        "id": "msg_1",
        "role": "assistant",
        "content": "Hi, how can I help you?",
        "createdAt": "2026-03-02T17:59:00.000Z"
      }
    ]
  }
}

When uploads are enabled and files are attached, the adapter sends multipart/form-data with:

  • message
  • sessionId
  • metadata (JSON string)
  • files[]

Accepted response shapes (default adapter)

Non-streaming JSON can return any of these fields:

  • message
  • text
  • output
  • response
  • answer
  • content

Streaming chunks can return:

{ "delta": "partial text" }
{ "delta": "partial text", "done": true }

SSE [DONE] is also supported.

API Highlights

Components

  • ChatbotProvider
  • ChatbotWidget
  • ChatbotPageConfig

Hooks

  • useChatbot
  • useChatbotSession

Complete prop reference

ChatbotProvider props

| Prop | Type | Required | Notes | | --- | --- | --- | --- | | webhookUrl | string | yes | Webhook endpoint used by the default adapter. | | children | ReactNode | yes | Usually includes ChatbotWidget. | | locale | string | no | Forces locale instead of auto-detection. | | localeTexts | ChatbotLocaleTextOverrides | no | Per-locale text overrides. | | agentName | string | no | Header title fallback. | | assistantNote | string | no | Header subtitle fallback. | | enableUploads | boolean | no | Enables file attachment UI and multipart webhook requests. | | streamingMode | "auto" \| "on" \| "off" | no | Controls stream parsing behavior. | | headers | Record<string, string> | no | Additional webhook request headers. | | theme | Partial<ChatbotThemeTokens> | no | Visual token overrides including typography. | | icons | Partial<ChatbotIcons> | no | Icon component overrides. | | branding | Partial<ChatbotBranding> | no | Header logo overrides. | | adapter | ChatbotAdapter | no | Transport/parsing customization. | | events | Partial<ChatbotEventHandlers> | no | Lifecycle/message callbacks. | | initialOpen | boolean | no | Opens the panel on initial render. | | position | "bottom-right" \| "bottom-left" | no | Bubble/panel anchor side. | | classNames | Partial<ChatbotClassNames> | no | Classname overrides for major widget regions. |

ChatbotWidget props

ChatbotWidget does not accept props.

ChatbotPageConfig props

| Prop | Type | Required | Notes | | --- | --- | --- | --- | | enabled | boolean | no | Temporarily hide/disable widget on a page. | | agentName | string | no | Page-level header title override. | | assistantNote | string | no | Page-level header subtitle override. | | enableUploads | boolean | no | Page-level upload toggle override. | | theme | Partial<ChatbotThemeTokens> | no | Page-level visual token overrides. | | branding | Partial<ChatbotBranding> | no | Page-level header logo override. |

Type references for nested props

ChatbotThemeTokens

| Token | Purpose | | --- | --- | | primary | Brand/accent color for interactive elements. | | primaryForeground | Foreground color on primary surfaces. | | background | Widget root background token. | | surface | Panel and card background token. | | surfaceForeground | Main text color on surface backgrounds. | | muted | Subtle background token. | | mutedForeground | Secondary text/icon color. | | border | Border color token. | | ring | Focus ring color token. | | userBubble | User message bubble background color. | | userText | User message text color. | | assistantBubble | Assistant bubble background color. | | assistantText | Assistant message text color. | | radius | Border radius token used across widget surfaces. | | fontFamily | Base font family used by the widget. | | shadowBubble | Box shadow token for launcher bubble. | | shadowPanel | Box shadow token for chat panel. | | fontSizeTitle | Header title font size. | | fontSizeSubtitle | Header subtitle font size. | | fontSizeBody | Message/body text font size. | | fontSizeMenu | Menu item font size. | | fontSizeInput | Composer input font size. | | fontSizeCaption | Caption/help text font size. | | inputMinHeight | Minimum composer input height. | | inputMaxHeight | Maximum composer input height before scrolling. | | inputLineHeight | Composer input line-height. |

ChatbotBranding

  • headerLogoUrl?: string
  • headerLogoAlt?: string

ChatbotClassNames

  • root?: string
  • bubble?: string
  • panel?: string
  • header?: string
  • headerMeta?: string
  • menu?: string
  • menuItem?: string
  • body?: string
  • footer?: string
  • composer?: string
  • input?: string
  • sendButton?: string

ChatbotIcons

  • launcher?: ComponentType<ChatbotIconProps> (legacy alias)
  • launcherClosed?: ComponentType<ChatbotIconProps>
  • launcherOpen?: ComponentType<ChatbotIconProps>
  • close?: ComponentType<ChatbotIconProps>
  • send?: ComponentType<ChatbotIconProps>
  • attach?: ComponentType<ChatbotIconProps>
  • bot?: ComponentType<ChatbotIconProps>
  • menu?: ComponentType<ChatbotIconProps>
  • expand?: ComponentType<ChatbotIconProps>
  • download?: ComponentType<ChatbotIconProps>

ChatbotEventHandlers

  • onOpen?: () => void
  • onClose?: () => void
  • onMessageSent?: (message: ChatMessage) => void
  • onChunkReceived?: (chunk: string) => void
  • onResponseComplete?: (message: ChatMessage) => void
  • onError?: (error: Error) => void
  • onAttachmentAdded?: (attachments: ChatAttachment[]) => void

ChatbotLocaleCopy keys

  • agentName
  • assistantNote
  • welcomeMessage
  • disclaimer
  • inputPlaceholder

Typography/font override example

<ChatbotProvider
  webhookUrl={process.env.NEXT_PUBLIC_CHATBOT_WEBHOOK_URL || ""}
  theme={{
    fontFamily: '"Space Grotesk", var(--font-sans), ui-sans-serif, system-ui, sans-serif',
    fontSizeTitle: "18px",
    fontSizeBody: "15px",
    fontSizeInput: "15px",
    fontSizeCaption: "12px",
  }}
>
  <ChatbotWidget />
</ChatbotProvider>

Locale overrides example

<ChatbotProvider
  webhookUrl={process.env.NEXT_PUBLIC_CHATBOT_WEBHOOK_URL || ""}
  localeTexts={{
    en: {
      welcomeMessage: "Hi, how can I help you?",
      disclaimer: "AI can make mistakes.",
      inputPlaceholder: "Ask something...",
    },
    de: {
      welcomeMessage: "Hi, wie kann ich dir helfen?",
      disclaimer: "KI kann Fehler machen.",
      inputPlaceholder: "Frag etwas...",
    },
  }}
>
  <ChatbotWidget />
</ChatbotProvider>

Precedence for text shown in the header:

  1. ChatbotPageConfig override
  2. ChatbotProvider props (agentName, assistantNote)
  3. resolved locale copy (localeTexts override + built-in defaults)

Tailwind Notes

The package ships compiled styles.css for the widget UI.

If you want Tailwind to see package class strings (for custom overrides), add one of these globs:

"./node_modules/@nickle-ai/chatbot-react/src/**/*.{ts,tsx}",
"./node_modules/@nickle-ai/chatbot-react/dist/**/*.{js,cjs}"

Build

npm run build --workspace @nickle-ai/chatbot-react

Troubleshooting

Install fails from npm

  • Confirm package name is exactly @nickle-ai/chatbot-react
  • Check your npm auth only if your environment requires it
  • Ensure your npm client can access the latest published version

Webhook returns but UI shows empty assistant response

  • Confirm response body includes recognized text fields (message, text, output, response, answer, content)
  • If using custom format, provide an adapter.parseJsonResponse

Streaming response not updating incrementally

  • Set streamingMode="on" while debugging
  • Ensure server returns SSE/line-delimited chunks compatible with adapter parsing

Browser blocks webhook requests

  • Verify CORS policy on your webhook endpoint allows the client origin and headers