TheaimartAIx DOCS
Home Get API key

Streaming a chat UI

Render answers token-by-token for that instant feel. Never put your AIx key in the browser — proxy through a server route, then stream the bytes to the client.

1 · Server route (Next.js App Router)

// app/api/chat/route.ts
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.aix.theaimart.co/v1",
  apiKey: process.env.AIX_KEY,   // server-side only
});

export async function POST(req: Request) {
  const { messages } = await req.json();
  const stream = await client.chat.completions.create({
    model: "deepseek-ai/DeepSeek-V3.2",
    messages,
    stream: true,
  });

  const encoder = new TextEncoder();
  const body = new ReadableStream({
    async start(controller) {
      for await (const part of stream) {
        const delta = part.choices[0]?.delta?.content ?? "";
        if (delta) controller.enqueue(encoder.encode(delta));
      }
      controller.close();
    },
  });
  return new Response(body, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
}

2 · Client component

"use client";
import { useState } from "react";

export default function Chat() {
  const [out, setOut] = useState("");
  async function send(prompt: string) {
    setOut("");
    const res = await fetch("/api/chat", {
      method: "POST",
      body: JSON.stringify({ messages: [{ role: "user", content: prompt }] }),
    });
    const reader = res.body!.getReader();
    const dec = new TextDecoder();
    for (;;) {
      const { value, done } = await reader.read();
      if (done) break;
      setOut((s) => s + dec.decode(value));
    }
  }
  return (
    <div>
      <button onClick={() => send("Explain async Rust in 3 lines")}>Ask</button>
      <pre>{out}</pre>
    </div>
  );
}
Tip

This route flattens chunks to plain text for simplicity. To forward full OpenAI SSE (so the client can use the OpenAI stream parser), pipe the upstream text/event-stream through instead.

Heads up

The AIx key lives only on the server (process.env.AIX_KEY). Don’t ship it to the browser.

Last updated July 18, 2026

Was this page helpful?