DEV Community

huangyongshan46-a11y
huangyongshan46-a11y

Posted on

Why Your SaaS Needs AI Chat in 2026 (Add It in 40 Lines)

70% of new SaaS products in 2026 include AI. Here is streaming chat in 40 lines — 20 for the server, 20 for the client.

Server

export async function POST(req: NextRequest) {
  const { messages } = await req.json();
  const res = await fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
    body: JSON.stringify({ model: "gpt-4o-mini", messages, stream: true }),
  });
  const stream = new ReadableStream({
    async start(c) {
      const r = res.body!.getReader(); const d = new TextDecoder();
      while (true) {
        const { done, value } = await r.read(); if (done) break;
        for (const l of d.decode(value).split("\n").filter(x => x.startsWith("data: "))) {
          const j = l.slice(6); if (j === "[DONE]") { c.close(); return; }
          try { const t = JSON.parse(j).choices?.[0]?.delta?.content; if (t) c.enqueue(new TextEncoder().encode(t)); } catch {}
        }
      }
      c.close();
    },
  });
  return new Response(stream);
}
Enter fullscreen mode Exit fullscreen mode

Client

const res = await fetch("/api/ai/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ messages }) });
const reader = res.body!.getReader(); const decoder = new TextDecoder();
let text = "";
while (true) { const { done, value } = await reader.read(); if (done) break; text += decoder.decode(value); updateUI(text); }
Enter fullscreen mode Exit fullscreen mode

40 lines. Streaming. No SDK. Any provider.

Conversation persistence + plan limits + full UI: LaunchKit ($49). GitHub

Top comments (0)