Fluxio
← Voltar ao blog

Server-Sent Events for Chat Developers: Step by Step

Notas de desenvolvimentoEN

§1 Step 1: Trace the Streaming Chat Request

Server-sent events, or SSE, let a server deliver successive text events over an HTTP response. Instead of returning one finished answer, your chat backend can keep the response open and send updates as generation progresses. SSE carries updates from server to client; submitting another user message requires a separate request. ([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events?utm_source=openai))

Sketch your application as three components: the browser, your backend, and the AI provider. Have the browser submit a message to your backend, then have your backend request generation and forward incremental results. Keep provider credentials on the backend rather than embedding them in browser code.

§2 Step 2: Choose EventSource or Streaming Fetch

The browser's native EventSource API handles SSE parsing and reconnection, but its constructor does not offer an arbitrary request body or custom authorization headers. Choose it when your application can open a separate event subscription using a URL and an appropriate authentication mechanism. ([html.spec.whatwg.org](https://html.spec.whatwg.org/multipage/server-sent-events.html))

For a chat endpoint that accepts a POST body, use fetch() and read response.body incrementally. Check response.ok before consuming the stream: Fetch does not reject its promise merely because the server returns an HTTP error. Do not call response.text() when you need incremental display, because that waits for the complete body. ([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch))

§3 Step 3: Request an Upstream AI Stream

Enable streaming on your provider request. For an OpenAI-style Chat Completions integration, this means setting stream: true and consuming the returned chunks instead of waiting for a complete response. Treat the provider's streaming schema as a separate layer from SSE framing. ([developers.openai.com](https://developers.openai.com/api/docs/guides/streaming-responses))

Fluxio fits here if you want a streaming-first, pay-per-token AI relay with one key across providers. Configure your OpenAI-style client's base URL as api.fluxioapi.com/v1, keep the key server-side, and select the documented model identifier for an option such as Gemini 2.5 Flash. This keeps provider access behind your backend while you build one browser-facing streaming contract.

§4 Step 4: Frame Complete SSE Messages

Your browser-facing response must use Content-Type: text/event-stream. SSE uses UTF-8 text, with a blank line marking an event boundary. Put payload text after data:; optionally use event: to name the event type. Multiple data lines within an event are joined with newline characters. ([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events?utm_source=openai))

Define your own application events for text updates, successful completion, and generation failure. These names are your contract, not mandatory SSE keywords. For example, send a named text update containing a JSON object with a text field, then terminate that event with a blank line.

§5 Step 5: Parse Events Before Updating Chat

With Fetch, decode incoming bytes incrementally using TextDecoderStream or a stateful decoder. Network chunks do not necessarily align with text lines, JSON objects, or SSE events. Preserve incomplete input between reads, and use an SSE parser that follows the event framing rules before parsing event payloads as JSON. ([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch))

Append decoded text updates to one assistant message rather than creating a bubble for every update. Batch visual updates when useful, preserve the user's scroll position, and treat generated text as untrusted content. Do not assume every provider event contains visible text; streaming APIs can also emit lifecycle or other structured events. ([developers.openai.com](https://developers.openai.com/api/docs/guides/streaming-responses))

§6 Step 6: Separate Cancellation From Reconnection

Connect your Stop button to an AbortController for Fetch, or call EventSource.close() for a native subscription. Propagate cancellation through your backend rather than only hiding further text. ([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch))

EventSource can reconnect automatically, but reconnecting does not inherently resume AI generation. SSE event IDs and Last-Event-ID support resumption only when your server implements replay. Without that mechanism, mark the partial reply as interrupted and offer an explicit retry instead of silently duplicating generation. ([html.spec.whatwg.org](https://html.spec.whatwg.org/multipage/server-sent-events.html))

§7 Step 7: Test the Deployed Streaming Path

  • – Verify that the first update appears before generation finishes.
  • – Test split characters, fragmented events, and multiline payloads.
  • – Test cancellation, authentication failures, and interrupted connections.
  • – Check that deployment proxies do not buffer the whole reply.
  • – Measure time to first visible text separately from total duration.

Sign up for Fluxio to build your streaming chat.

Criar uma conta Fluxio →

Mais da corrente