Shakomako, the chat widget
Shakomako is the chat widget that websites embed to talk to an agent. A site
adds one <script> tag, and Shakomako shows a chat bubble in the corner or a
floating "ask anything" bar. The name is Iraqi slang, roughly "what's up?".
Shakomako is its own open-source project, chatvia/shakomako, under the MIT license. It imports nothing from Chatvia. It knows the address of a server and a small HTTP API, nothing more, so it works with Chatvia or with a backend you write yourself.
What it does
- Two launchers: a chat bubble, or a bar (
data-mode="bar"). - Streaming answers: the reply appears while the server writes it, over Server-Sent Events (SSE).
- Markdown in answers: lists, links, tables and code.
- Conversation history: after a reload the visitor picks up where they left off. They can also open older conversations, start new ones and delete them.
- 20 languages, taken from the browser or set on the embed tag.
- Light and dark themes, in the agent's brand color.
- More when the server supports it: file uploads, thumbs up and down, forms inside answers, tool activity ("Searching the web…"), the sources of an answer, a model picker, dictation, voice calls and live chat with a person.
- A JavaScript API for your own page:
chatvia.open(),chatvia.send('Hello'),chatvia.on('ready', …).
How it loads
Your website
↓ <script src=".../embed.js" data-agent-id="…">
embed.js the small loader, the only file a site embeds
↓ fetch version.json which release is current
{version}/widget.min.js the widget itself
↓ HTTP and SSE
Your server {api}/agents/settings, {api}/stream, …A site never changes its snippet: a new release only changes
version.json. Every release has a folder with a new name, so browsers and
CDNs can cache it for good.
Works with any backend
Shakomako has no Chatvia code and no built-in idea of what an agent is. It gets everything from the server while it runs:
- What to show. The title, brand color, welcome message, conversation starters, window size and the rest come from one settings response. Nothing is compiled into the widget.
- What to answer. The widget posts the visitor's message and shows the text the server streams back. How the server finds that text is up to you: a large language model, a search index, a rules engine, or a person.
- Which bot.
data-agent-idis a string that the widget sends in theX-Agent-Idheader. Your server decides what it means, so one server can run many bots.
So any server that speaks the backend API works: Chatvia, a Laravel, Node, Python or Go app you already run, a thin proxy in front of an LLM provider, or an echo server for tests. The API is JSON over HTTP plus one SSE stream. You need no SDK, and no WebSocket server unless you want live chat.
What the widget can do grows with what you build. Seven endpoints give you a working chat with history. Add more for feedback, uploads, forms and live chat. See Which endpoints you need.
Point it at a server
The widget finds its API in this order:
- The
data-api-urlattribute on the embed tag. VITE_API_URL, when the widget was built./widgeton the server thatembed.jscame from. This is how Chatvia serves it.
<script id="chatbot-embed-script"
src="https://cdn.example.com/shakomako/embed.js"
data-agent-id="support-bot"
data-api-url="https://api.example.com/widget"
defer></script>Each endpoint path is added to that URL, like
https://api.example.com/widget/stream.
Embed attributes
| Attribute | Meaning |
|---|---|
data-agent-id |
Required. Sent to your server as X-Agent-Id. |
data-mode |
bubble (default) or bar. |
data-language |
auto (default) follows the browser. Or one of ar, da, de, en, es, fa, fi, fr, hi, id, ja, ko, no, pl, pt, ru, sv, tr, vi, zh. Other codes fall back to English. |
data-theme |
auto, light or dark. Without it, the server's theme setting applies. |
data-mount-id |
The id of an element to render the widget into, instead of the page corner. |
data-auth |
A signed token, only for a protected agent. |
data-api-url |
The API base URL. See above. |
data-reverb-host, data-reverb-port, data-reverb-key, data-reverb-scheme |
The WebSocket server for live chat. They win over the values the server sends. |
Host the widget yourself
A Chatvia server builds Shakomako and serves it at /shakomako/embed.js. To
serve it from somewhere else, such as a CDN, build it with Node.js 22.18 or
newer:
git clone https://github.com/chatvia/shakomako.git
cd shakomako
npm ci
npm run buildUpload the contents of dist/: embed.js, version.json and the release
folder. Keep them next to each other. Other websites read version.json
with fetch(), so the host must send Access-Control-Allow-Origin: *. Cache
the release folder for a long time, and version.json not at all. The
nginx settings for Chatvia work for any
host.
To bake your server's address into the build instead of setting
data-api-url on every tag, copy .env.example to .env and set
VITE_API_URL before you build.