vilow.dev · Integrations · Netlify
Add Vilow to a Netlify site
Netlify Functions (or Edge Functions) are the standard way to keep an
API key server-side on Netlify. Works with any frontend stack — React,
Vue, Astro, Eleventy, plain HTML — the function endpoint is just a
/.netlify/functions/... URL the browser calls.
-
Get a Vilow API key
vilow.dev/dashboard → API keys → Create.
-
Add the key to Netlify env vars
In Netlify: Site configuration → Environment variables → Add:
VILOW_API_KEY = ck_live_... VILOW_API_BASE = https://api.vilow.dev/v1
Apply to All deploy contexts (Production + Deploy Previews + Branch deploys).
-
Create a Netlify Function
Add a file
netlify/functions/vilow-chat.ts:import type { Context } from "@netlify/functions"; const KEY = Netlify.env.get("VILOW_API_KEY")!; const API = Netlify.env.get("VILOW_API_BASE") ?? "https://api.vilow.dev/v1"; export default async (req: Request, _ctx: Context) => { if (req.method !== "POST") return new Response("POST only", { status: 405 }); 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: "Netlify 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", 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 Response.json({ ...(await chat.json()), character_id: cid }); };
-
Call the function from your frontend
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("/.netlify/functions/vilow-chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: uid, character_id: cid && +cid, message: text }), }); const d = await r.json(); if (d.character_id) localStorage.setItem("vilow_cid", "" + d.character_id); return d.reply; }
-
Run locally with Netlify CLI
npm i -g netlify-cli netlify dev
That spins up your frontend + functions on a single port and pulls env vars from Netlify automatically. Send a test message — you should get back a stateful reply.
-
Deploy
netlify deploy --prod
Custom domain: Site configuration → Domains. Vilow's CORS already allows
*.netlify.apppreviews.
Edge Functions (lower latency)
Same code in netlify/edge-functions/vilow-chat.ts runs on
Deno at the edge — ~50ms cold start vs ~600ms for AWS-Lambda-backed
Functions. Worth it if your audience is global and you care about TTFB.
Common gotchas
- 500 from the function with no error in browser — check Netlify Functions → Logs. Most often it's a typo in the env var name.
- Build doesn't pick up the function — TypeScript functions need
esbuildbundler, set innetlify.toml:[functions] node_bundler = "esbuild". - Local
netlify devdoesn't see env vars — link the site first:netlify link, then it pulls them.