# rony-chat-widget A drop-in vanilla-JS chat widget that talks to the Rony Chat Bot backend over Server-Sent Events. No build step, no runtime dependencies, no global CSS pollution. ## Files | File | Purpose | |---|---| | `chat-widget.js` | The widget. Self-contained ~12 KB. | | `chat-widget.css` | Scoped styles, themable via CSS custom properties. | | `example.html` | Standalone demo page (use with `python3 -m http.server`). | ## Quick start (any site) ```html ``` The bubble appears bottom-right (or bottom-left), opens a 380×560 panel, and talks to `data-api-url/api/chat` over SSE. ## Configuration (all via `data-*` attributes on the ` ``` ## Theming (override without forking) All visual tokens are CSS custom properties on the root element. Set them in your site's stylesheet: ```css .rony-chat-widget-root { --rony-accent: #ff6b35; /* bubble + send button + links */ --rony-radius: 4px; /* tighter corners */ --rony-font: "Inter", sans-serif; } ``` See the full list in `chat-widget.css` (search for `--rony-`). ## Astro integration The simplest path is the drop-in. Add this to your `Layout.astro` (or any shared layout): ```astro --- // src/layouts/ChatLayout.astro import "../path/to/chat-widget.css"; const apiUrl = import.meta.env.PUBLIC_CHAT_API_URL || "http://localhost:7331"; --- ``` Notes: - `is:inline` keeps Astro from hashing/transforming the script tag, so the `data-*` attributes survive. - `PUBLIC_CHAT_API_URL` is an Astro env var; set it in `.env` per environment. - The bot's `cors_origins` in YAML must include your Astro dev origin (`http://localhost:4321`). ## React/Next.js Mount the same script tag in your root layout: ```tsx // app/layout.tsx import Script from "next/script"; export default function RootLayout({ children }) { return ( ``` Or expose a "new chat" button in your UI that calls `DELETE /api/conversations/{id}` then clears the localStorage key. ## What's not in the widget (yet) - **Markdown images / tables** — the renderer handles paragraphs, lists, code, links, bold/italic. Tables and images render as raw text. For richer output, swap `renderMarkdown` for `marked` or `markdown-it`. - **Typing indicators beyond the streaming caret** — the caret at the end of the streaming response is the only indicator. Good enough for short answers. - **Mobile sheet drag-to-dismiss** — the panel goes full-screen on phones, but can't be swiped away. Add a swipe handler if it matters. - **Conversation history sidebar** — only the active conversation is shown in the panel. The backend exposes `GET /api/conversations` for a future sidebar.