Server-Sent Events (SSE) let a server push new data to an HTML page at any time. Traditionally the page must request updates; with SSE the server streams messages and your page script treats them as events—then updates the DOM (lists, clocks, alerts) without reloading.
What does the HTML page do?
A script creates an EventSource pointed at a stream URL. Incoming messages become message events (or named events). Handlers read event.data and change HTML elements—the connection stays open so updates keep arriving.
What does the server send?
A UTF-8 text stream with MIME type text/event-stream. Each event is one or more field lines (data:, optional event:, id:, retry:) ended by a blank line.
When should you use SSE on an HTML site?
Live scores, notification feeds, dashboards, and progress updates—anywhere the server talks and the browser mostly listens. For two-way chat or games, prefer WebSockets instead.
One-way only.
SSE cannot send events from the client to the server. Use normal HTTP forms/fetch for client→server actions.
Connection limits on HTTP/1.1.
Browsers often allow only a few SSE connections per domain across tabs (~6). HTTP/2 raises that limit. Prefer HTTP/2 in production.
Auto-reconnect.
If the stream drops, EventSource reconnects by default. Call close() when the HTML page no longer needs updates.
Syntax
HTML / Client Syntax
Open a stream from a script in your HTML document:
JS
var evtSource = new EventSource("/sse");
evtSource.onmessage = function (event) {
// event.data is a string — update the HTML page
document.getElementById("out").textContent = event.data;
};
evtSource.onerror = function () {
console.error("EventSource failed");
};
// Stop listening (optional)
// evtSource.close();
stream-format.txt
: keep-alive comment
data: some text
event: ping
data: {"time":"2026-11-05T07:40:00Z"}
Cross-origin streams can pass options: new EventSource(url, { withCredentials: true }).
Reference
Core HTML Concepts
Pieces that connect a live stream to your webpage:
Concept
Role
EventSource
Browser API that opens and reads the SSE connection
text/event-stream
Required MIME type for the server response
data:
Payload line(s); concatenated into event.data
event:
Named event type (listen with addEventListener)
id:
Last-Event-ID for resume after reconnect
retry:
Reconnection delay in milliseconds
onmessage
Handler for default (unnamed) messages
close()
Stop the stream from the HTML page
DOM update
Write event.data into elements, lists, or status text
Event stream fields
Field
Effect in the browser
data
Becomes event.data (multi-line data: joined with newlines)
event
Dispatches a custom event name instead of message
id
Sets last event id; sent back on reconnect as Last-Event-ID
retry
How long to wait before reconnecting (ms)
: comment
Ignored; useful as a keep-alive heartbeat
Approach
How to Use SSE in an HTML Page
Client first (what every HTML tutorial needs), then a minimal server shape.
Add HTML placeholders for live content (<ul id="list">, <div id="clock">).
In a script, new EventSource("/your-stream").
Handle onmessage to update the DOM from event.data.
For named server events, use addEventListener("ping", …).
Handle onerror; call close() when leaving the page or stopping the feed.
On the server: respond with text/event-stream and write data: …\n\n blocks.
Goal
Pattern
Connect from HTML
new EventSource("/sse")
Show default messages
es.onmessage = (e) => { … e.data … }
Named event
es.addEventListener("news", handler)
Stop updates
es.close()
Server event body
data: Hello\n\n with Content-Type: text/event-stream
Try it
Live Preview
Simulate an SSE feed updating an HTML list (same handler pattern as real EventSource.onmessage).
Simulated stream in the browser—no backend required. Real pages use new EventSource(url).
HTML preview
(clock idle)
evtSource.onmessage = (e) => append(e.data)
Code
HTML Examples
Five patterns: server stream shape, client EventSource, errors, custom events, and a full HTML clock page. Try It demos simulate the stream so you can practice handlers without Node.
Example 1 — Minimal SSE Server (Node.js)
Respond with text/event-stream and push a time string every second:
One line: Stream text/event-stream from the server → EventSource in the HTML page → update the DOM from event.data.
Frequently Asked Questions
SSE lets a server push text updates to your HTML page over one long-lived HTTP connection. A script creates an EventSource, listens for message (or named) events, and updates the DOM—without the page polling.
SSE is one-way (server → browser) over ordinary HTTP with a simple text stream. WebSockets are two-way and use a different protocol. Prefer SSE for live feeds, notifications, and dashboards where only the server sends updates.
EventSource is the browser API for SSE. Call new EventSource(url), handle onmessage or addEventListener for custom types, and optionally onerror. The browser reconnects automatically if the connection drops unless you call close().
Content-Type: text/event-stream, usually with Cache-Control: no-cache. Each event is UTF-8 text lines ending with a blank line (two newlines), for example data: Hello followed by \n\n.
In onmessage, read event.data (a string) and write it into the page—textContent on an element, append a list item, or JSON.parse then fill several fields.
Messages with an event: field become custom events. Listen with addEventListener("ping", …). Messages without event: fire the default message event (onmessage).