vilow.dev · Integrations · Bolt.new
Add Vilow to a Bolt.new app
Bolt.new (by StackBlitz) generates full-stack apps in a WebContainer browser
sandbox — usually Vite + Express, Next.js or Hono. Because Bolt has a real
Node.js runtime, you can keep the Vilow API key in .env and call
it from a server-side route. No external proxy needed.
-
Get a Vilow API key
Sign in at vilow.dev/dashboard → API keys → Create. Copy the
ck_live_…string. -
Add the key to
.envin your Bolt projectOpen the file tree, edit
.env(Bolt creates it automatically; if not, ask Bolt: "add a .env file with VILOW_API_KEY").VILOW_API_KEY=ck_live_... VILOW_API_BASE=https://api.vilow.dev/v1
Don't useVITE_VILOW_API_KEYor anyVITE_/NEXT_PUBLIC_prefix — those bake the value into the client bundle. Plain env vars stay server-only. -
Add a server route handler
For a Bolt-generated Next.js project, create
app/api/vilow-chat/route.ts:import { NextResponse } from "next/server"; const KEY = process.env.VILOW_API_KEY!; const API = process.env.VILOW_API_BASE ?? "https://api.vilow.dev/v1"; export async function POST(req: Request) { const { user_id, character_id, message } = await req.json(); let cid = character_id; if (!cid) { await fetch(`${API}/users`, { method: "POST", headers: { "X-API-Key": KEY, "Content-Type": "application/json" }, body: JSON.stringify({ external_id: user_id, display_name: "Bolt visitor" }), }); const r = await fetch(`${API}/users/${user_id}/characters`, { method: "POST", headers: { "X-API-Key": KEY, "Content-Type": "application/json" }, body: JSON.stringify({ name: "Aria", gender: "female", default_language: "auto" }), }); cid = (await r.json()).id; } const chat = await fetch(`${API}/chat/${user_id}/${cid}/send`, { method: "POST", headers: { "X-API-Key": KEY, "Content-Type": "application/json" }, body: JSON.stringify({ message }), }); return NextResponse.json({ ...(await chat.json()), character_id: cid }); }
For Vite + Express: same logic, just an Express route — Bolt's AI will rewrite it for you if you ask.
-
Call the route from React
async function send(text) { const uid = localStorage.getItem("vilow_uid") ?? (() => { const u = "u_" + crypto.randomUUID(); localStorage.setItem("vilow_uid", u); return u; })(); const cid = localStorage.getItem("vilow_cid"); const r = await fetch("/api/vilow-chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: uid, character_id: cid && Number(cid), message: text }), }); const data = await r.json(); if (data.character_id) localStorage.setItem("vilow_cid", String(data.character_id)); return data.reply; }
-
Test in Bolt's WebContainer
Bolt's preview URL is something like
{hash}--{slug}.bolt.new. Vilow's API allows that origin out of the box — your route handler is server-side anyway, so the browser never touches Vilow directly. -
Deploy
Bolt offers one-click deploy to Netlify, Vercel, or GitHub. Whichever you pick, copy
VILOW_API_KEYinto the platform's environment variables before the build.
Common gotchas
- Env var not picked up — restart the dev server after editing
.envin Bolt. WebContainer caches env at boot. - "Cannot find module 'next/server'" — Bolt may have generated a Vite project, not Next.js. Adapt the example to whatever framework Bolt picked.
- Slow first response (~30-60s) — that's normal for tool-calling turns where the LLM searches/decides. Subsequent turns are quick. Show a typing indicator.