Add a chat assistant
Optional AI or human chat on every page, with your site as its knowledge base.
Meteorite has first-class, optional support for PopTalk: a self-hosted chat backend with a small widget, which can answer with an AI model or forward messages to you, and poptalk-rag, which lets it answer from your own content. Nothing is added to your site unless you turn it on.
A static site cannot run a chatbot by itself, so there are two parts:
| Part | Where it runs | What it does |
|---|---|---|
| PopTalk backend (and optionally poptalk-rag) | Your own server | Talks to the AI provider or to you; holds all keys |
| Meteorite | Build time | Adds the widget to your pages and exports your content as the knowledge base |
1. Turn on the widget #
# config.yml
chat:
provider: poptalk
api_url: https://chat.example.com # your PopTalk backend
persona: my-site # optional, for multi-persona backends
That is all. Both bundled themes already include the hook; a custom theme needs one line before </body>:
{{ chat_widget() | safe }}
Check the backend, including that it allows your site’s origin (CORS):
What visitors get #
- A launcher button. Nothing is requested from the chat backend until it is clicked, so there are no cookies or network calls before the visitor chooses to chat.
- The widget file is copied into your site (
assets/poptalk-<hash>.js, with a subresource integrity hash and its MIT licence), so no CDN is contacted. Fonts come from the visitor’s system by default; setfonts: googleto use Inter from Google Fonts. - The widget follows your site’s light/dark mode and skin accent live.
- Before the first message the widget asks for a name and a valid email address (or phone number with
data-collect="phone"). PopTalk 1.2 or later requires this; there is no anonymous mode.
Options #
| Key | Default | Meaning |
|---|---|---|
provider | none | poptalk enables chat |
api_url | none | Backend base URL (required when enabled) |
persona | backend default | Persona id |
lang | visitor’s browser | en, fr, pt, … |
theme | auto | auto follows the site; or dark / light |
accent | auto | auto follows the site accent; or any CSS colour |
load | click | click (launcher), idle, or immediate |
widget | bundled | bundled, or an https:// URL you manage |
fonts | system | system or google |
label | Chat | Launcher text |
welcome | persona’s welcomeMessage | First line in the chat window, for example Ask me about Meteorite themes. Plain text, 200 characters at most. Without it the widget uses the persona’s welcomeMessage from the backend, or a generic greeting |
2. Use your site as the knowledge base (optional) #
poptalk-rag indexes documents in knowledge/<persona>/. Point Meteorite at that folder and every meteorite build keeps it in sync:
chat:
provider: poptalk
api_url: https://chat.example.com
knowledge:
dir: ../poptalk-rag/knowledge/my-site
exclude: # sections to leave out; `include:` limits instead
rag_url: https://rag.example.com # only for `meteorite chat sync`
Each published page becomes one Markdown file with the front matter needed to cite it:
---
title: Getting started
url: https://example.com/guide/getting-started/
section: guide
date:
tags:
---
What is exported, and what is not:
- Only what you publish: drafts, future-dated and expired pages are left out.
- Shortcodes become their plain text, and the home page’s
hero,features,stats,showcase,quoteandctablocks become prose, so nothing a visitor can read is missing. - Add
chat: falseto a page’s front matter to keep it out. - Meteorite only ever touches files it created (it keeps a
.meteorite-exportlist). Your own documents in the same folder are left alone, and it refuses to overwrite a file it didn’t write. - The folder must be outside the site (not
content/,themes/,public/or the site root). serveandchecknever export;meteorite build --no-exportskips it too.
Getting the knowledge to poptalk-rag #
poptalk-rag reads a folder, and your server is usually not the machine that builds the site. Pick the delivery that fits:
| How | When to use it | |
|---|---|---|
| Publish and pull (recommended) | Meteorite publishes knowledge.json with the site; poptalk-rag fetches it | The site and the RAG server are on different hosts |
| Shared folder | chat.knowledge.dir points straight at poptalk-rag’s knowledge/<persona>/ | Build and RAG run on the same machine, or share a volume |
| Copy in CI | meteorite build, then rsync the export folder to the server | You already deploy by SSH |
Publish and pull #
chat:
provider: poptalk
api_url: https://chat.example.com
knowledge:
publish: true # writes public/knowledge.json with the site
On the poptalk-rag server:
KNOWLEDGE_SITE_SOURCES=my-site=https://example.com/knowledge.json
That is the whole setup. There is nothing to upload, no SSH key in CI and no extra credential: what poptalk-rag fetches is exactly what is live, and it is only content that is already public.
knowledge.json is a versioned, deterministic file (no timestamps; documents ordered by path), with a content hash per document and a digest for the whole file:
poptalk-rag uses it conservatively: an unreachable site, a bad response, an unknown version or an empty list changes nothing, so a site outage never erases a knowledge base. Unchanged sites cost one conditional request. Change the file name with knowledge.publish_path.
Re-index immediately #
poptalk-rag polls on its own (every 10 minutes for site sources). To trigger a pass right after a deploy, for example from CI:
# the persona's key; never put it in config.yml
Privacy and security #
- Keys never enter the site.
config.ymlis published with your site, so Meteorite refuses anychat:key that looks like a credential (api_key,token,secret, …). The persona key is read from the environment variable named bychat.knowledge.key_env. - Messages go to your backend and then to the AI provider you configured there. Say so in your privacy notice.
- Keep
load: clickunless you have a reason not to; it is what makes “no request before the visitor opts in” true.