</>
Skip to content
HTML lessons (53/60)

HTML — SSE

Friendly Intro – What & Why

Server‑Sent Events (SSE) let a web page receive real‑time updates only from the server.
Think of a live news ticker, a stock price feed, or a chat room that only needs one‑way communication.
Unlike WebSockets, SSE is built on top of normal HTTP and is simpler to use when you don’t need two‑way traffic.

  • One‑way: Server → Browser
  • Text‑based: Data is plain text, no binary framing
  • Automatic reconnect: The browser will try to reconnect if the connection drops
  • Easy to debug: You can open the SSE URL directly in a browser and see the raw stream

1. How SSE Works Under the Hood

  1. The browser creates an EventSource object pointing to a URL.
  2. The server responds with Content-Type: text/event-stream and keeps the connection open.
  3. The server sends data in a simple format:
    data: Hello World
    \n\n
    
  4. The browser parses each block and triggers a message event.
  5. If the connection closes, the browser automatically retries after a short delay.

2. Server‑Side Setup (Node.js Example)

Below is a minimal Node.js server that streams a timestamp every second.
You only need this to see SSE in action; the client side is the focus of this lesson.

// sse-server.js
const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/time') {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
    });

    const sendTime = () => {
      const now = new Date().toLocaleTimeString();
      res.write(`data: Current time is ${now}\n\n`);
    };

    // Send every second
    const interval = setInterval(sendTime, 1000);

    // Clean up on client disconnect
    req.on('close', () => {
      clearInterval(interval);
    });
  } else {
    res.writeHead(404);
    res.end();
  }
});

server.listen(3000, () => console.log('SSE server listening on http://localhost:3000'));

Good to know:
The \n\n (double newline) marks the end of one message.
If you forget it, the browser will wait forever for the next block.


3. Client‑Side: Basic SSE Connection

Create an index.html file that connects to the server we just wrote.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Demo</title>
</head>
<body>
<h2>Live Clock from Server</h2>
<div id="clock">Waiting for data…</div>

<script>
  const source = new EventSource('http://localhost:3000/time');

  source.onmessage = event => {
    document.getElementById('clock').textContent = event.data;
  };

  source.onerror = () => {
    console.error('SSE connection error');
  };
</script>
</body>
</html>

What the browser displays

The page shows “Live Clock from Server” and a box that updates every second with the current time sent by the server.


4. Using Custom Event Types

The server can send named events so the client can handle them separately.

// Inside the setInterval in server
res.write(`event: tick\n`);
res.write(`data: Tick at ${new Date().toLocaleTimeString()}\n\n`);

Client side:

source.addEventListener('tick', e => {
  console.log('Custom event tick:', e.data);
});

What the browser displays

The console logs “Custom event tick: Tick at …” every second, while the page still updates the clock.


5. Reconnection Options

EventSource accepts an options object.
The most common is reconnectTime (milliseconds).

const source = new EventSource('http://localhost:3000/time', {
  reconnectTime: 5000  // wait 5 seconds before reconnecting
});

6. Table: EventSource Options & Their Effects

OptionTypeDefaultWhat It Does
withCredentialsBooleanfalseSends cookies / auth headers
reconnectTimeNumber3000 (3 s)Delay before auto‑reconnect
onopenFunctionnullCalled when connection opens
onmessageFunctionnullHandles generic message events
onerrorFunctionnullHandles errors & reconnect attempts

Common mistake:
Forgetting to set reconnectTime can cause rapid reconnect loops if the server is down.


7. Error Handling and Cleanup

source.onerror = event => {
  if (event.eventPhase === EventSource.CLOSED) {
    console.warn('Connection closed.');
  } else {
    console.error('SSE error:', event);
  }
};

// When page unloads, close the connection
window.addEventListener('beforeunload', () => source.close());

8. Security Considerations

  • SSE uses the same origin policy as normal HTTP requests.
  • If you need to send sensitive data, use HTTPS and authenticate the SSE endpoint.
  • Do not expose SSE endpoints that reveal user data without proper checks.

9. Common Mistakes Checklist

  • Missing double newline (\n\n) after each message.
  • Not setting Content-Type: text/event-stream on the server.
  • Using fetch instead of EventSource.
  • Leaving the connection open after the user navigates away.
  • Not handling reconnection when the server is temporarily unreachable.

10. Mini Practice

  1. Add a second event called alert that sends a warning message every 10 seconds.
    Update the client to log these alerts to the console.

  2. Display the number of reconnect attempts on the page.
    Increment a counter each time onerror fires.

  3. Create a button that pauses the clock.
    When clicked, call source.close() and change the button text to “Resume”.

  4. Implement authentication: modify the server to check for a cookie before streaming.
    If the cookie is missing, respond with 401 Unauthorized.

  5. Use withCredentials to send a cookie from the client.
    Verify on the server that the cookie is received.


Related Topics

Frequently Asked Questions about SSE

What is SSE in HTML?

SSE is a fundamental concept in HTML. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn SSE?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn SSE.

Why is SSE important in HTML?

SSE is essential for HTML development. Understanding this concept will help you write better code and solve real-world problems more effectively.