Website integration
Add the tourism chatbot to your site
Use the same API from a WordPress site, Next.js app, static HTML, or mobile client. Guests ask about packages; your knowledge base answers.
1. Keep the tenant key server-side when you can
For production, proxy chat through your backend so the tenant api_key is not exposed in browser source. For demos, the key can live in the client (as on /demo).
2. Minimal browser fetch
async function askTourBot(message, sessionId, apiKey) {
const res = await fetch("https://tourragapi.vercel.app/api/v1/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify({
message,
session_id: sessionId,
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error || "Chat failed");
}
return res.json(); // { answer, sources, session_id }
}3. Floating chat bubble (recommended)
One script tag — same style operators expect (bottom-right bubble). Hosted at https://tourragapi.vercel.app/tour-rag-widget.js. Preview it on /demo after pasting a tenant key.
<!-- Paste before </body> on WordPress / HTML / any site -->
<script
src="https://tourragapi.vercel.app/tour-rag-widget.js"
data-api-key="YOUR_TENANT_KEY"
data-api-base="https://tourragapi.vercel.app/api/v1"
data-title="Safari Assistant"
data-primary="#0d8f5b"
defer
></script>Brand it with data-primary (hex color), data-title, and data-welcome. For production traffic, proxy chat through your server so the key is not public.
4. Inline panel (optional)
If you prefer a fixed chat box in the page (not a floating bubble):
<div id="tour-rag-chat" style="max-width:420px;font-family:system-ui">
<div id="tour-rag-log" style="min-height:120px;border:1px solid #ddd;padding:12px;border-radius:12px"></div>
<form id="tour-rag-form" style="display:flex;gap:8px;margin-top:8px">
<input id="tour-rag-input" placeholder="Ask about safaris..." style="flex:1;padding:10px" />
<button type="submit">Send</button>
</form>
</div>
<script>
(function () {
var KEY = "YOUR_TENANT_KEY";
var SID = "site-" + Math.random().toString(36).slice(2);
var log = document.getElementById("tour-rag-log");
document.getElementById("tour-rag-form").onsubmit = async function (e) {
e.preventDefault();
var input = document.getElementById("tour-rag-input");
var msg = input.value.trim();
if (!msg) return;
input.value = "";
log.innerHTML += "<p><b>You:</b> " + msg + "</p>";
var res = await fetch("https://tourragapi.vercel.app/api/v1/chat", {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": KEY },
body: JSON.stringify({ message: msg, session_id: SID })
});
var data = await res.json();
log.innerHTML += "<p><b>Assistant:</b> " + (data.answer || data.error) + "</p>";
};
})();
</script>How much content can one tenant ingest?
Per request: up to 50 chunks, each up to 8,000 characters (~1.5–2k tokens per chunk roughly). Call ingest many times to grow the knowledge base.
Whole website with ~1,000 pages? Yes in principle — but not as one raw dump. Scrape → clean → split into chunks (~500–1,500 words) → batch ingest (e.g. 20–50 chunks per request). Expect on the order of thousands of vectors for a large site, not one vector per full page.
Practical limits today: Gemini embedding rate limits, Vercel function time (embed each chunk in series), Supabase storage, and retrieval quality (we only return the top 4 matches per question). For sales demos, start with 20–100 high-value FAQ/package chunks — not 1,000 noisy HTML pages.
SEO tip for operators
When you embed chat, still keep crawlable FAQ pages for Kilimanjaro routes, Serengeti packages, and park fees. The chatbot improves conversion; public HTML pages improve Google rankings. Point your sitemap at both.
Talk to the builder
Need this on your tourism website?
Call or message Cleven for demos, custom knowledge bases, multi-tenant setup, or embedding the chat widget on your operator site.