Fluxio
← Back to the blog

Vue and Svelte Chat Interfaces with Token Streaming

What tokens costEN

§1 Design the token stream before building the chat interface

A streaming chat interface shows an assistant’s reply as it arrives, letting readers start reading while generation continues. Vue and Svelte both support this interaction well: the browser consumes a response stream, updates one assistant message, and keeps the conversation usable throughout generation.

Build the same architecture for either framework: a chat component sends messages to your backend, and the backend forwards a streaming request to an AI provider. The browser receives server-sent event data through a streaming fetch response. Keep provider credentials exclusively on the server.

§2 Step 1: Connect a backend route to Fluxio

Create a POST /api/chat route that accepts a messages array. Validate message roles and content, limit request size, and apply authentication and usage limits before contacting the provider.

Fluxio fits this setup because it is a streaming-first, pay-per-token AI API relay with an OpenAI-compatible interface. Configure an OpenAI-style client with https://api.fluxioapi.com/v1 as its base URL and load the API key from a server environment variable. One key provides access to multiple model families without changing your frontend transport.

Choose an available model, such as Claude Haiku 4.5 or Gemini 2.5 Flash, using its exact identifier from the provider’s model listing. Send the conversation to the chat completions endpoint with stream: true. Forward text content as it arrives instead of waiting for a complete answer.

§3 Step 2: Define an SSE contract for the browser

Make the backend emit a small, consistent event format. For example, send each text fragment as a data event containing a JSON object with a delta field. Finish with a done event, and use an error event for failures that occur after streaming has begun. Normalizing upstream chunks keeps provider-specific details out of both components.

Return Content-Type: text/event-stream and Cache-Control: no-cache. Ensure your hosting platform and reverse proxy allow streaming and disable response buffering where needed. Flush events promptly; buffering can make a working token stream appear as one delayed response.

Use fetch rather than the browser’s native EventSource because the chat request carries a POST body. Read response.body with a reader and decode bytes with TextDecoder in streaming mode.

§4 Step 3: Parse SSE across arbitrary network chunks

A network read does not correspond to one token or one event. A read can contain several events, half an event, or part of a multibyte character. Keep an accumulated text buffer and extract only complete SSE events.

  • – Normalize line endings while preserving incomplete data between reads.
  • – Separate events at blank lines and combine multiple data lines within each event.
  • – Parse JSON only after assembling the complete event payload.
  • – Append delta text to the active assistant message and stop on the explicit completion event.

Check the HTTP status before reading the stream. Treat an unexpected connection close without a completion event as an interrupted reply. Put this parser in a shared utility so Vue and Svelte use identical transport logic.

§5 Step 4: Update a Vue assistant message incrementally

In Vue, store messages in a ref containing objects with stable IDs, roles, and content. On submission, capture the outgoing conversation, append the user message, and create an empty assistant message. Send only the intended conversation history, excluding that empty placeholder.

As each delta arrives, append it to the assistant object’s content. Vue tracks these reactive updates. Render messages with stable keys and display content as text. If you support Markdown, sanitize rendered HTML and account for incomplete formatting during generation.

§6 Step 5: Update Svelte state with the same stream

In Svelte 5, declare the messages array with $state and create the same user and assistant entries. Append incoming text to the active assistant’s content; deeply reactive state updates the rendered message. With legacy Svelte reactivity, reassign the messages array after changing message content so the update is detected.

In either framework, batch frequent fragments into one update per animation frame if rendering becomes expensive. Auto-scroll only when the reader is already near the bottom.

§7 Step 6: Add cancellation and test interrupted replies

Create an AbortController for each request and connect a Stop button to abort(). Propagate browser disconnection to the upstream request on the backend. Preserve partial text, mark its status, and clear the generating state in a finally block.

Test split events, Unicode characters, provider errors, cancellation, and slow connections. Confirm that the first text appears before completion and that secrets never reach browser requests.

Sign up for Fluxio to build your streaming chat.

Create a Fluxio account →

More from the current