Real-Time Updates with Server-Sent Events (SSE) in Next.js 15
Stream multiple named events from a Next.js 15 endpoint and consume them via the useEventSource hook from react-use-websocket.
Server-Sent Events (SSE) provide a straightforward way to push server updates to the client over HTTP—no complex WebSocket handshake required. In this tutorial, we’ll create an SSE endpoint in Next.js 15 (with the App Router) that sends multiple named events—think “news” headlines and “stats” updates—and consume them in the browser with the useEventSource
hook from the react-use-websocket
library.
1. Project Setup
Create a new Next.js 15 project with the App Router, a src
directory, and TypeScript:
This creates a folder structure like:
Then install react-use-websocket
:
2. Creating an SSE Endpoint
We’ll create a streaming endpoint that periodically sends two different named events:
- news: Simulated “breaking news” headlines.
- stats: Random numeric data, like “active users” or “sales figures.”
Create a file at src/app/api/stream/route.ts
:
Key Points
- Multiple Named Events:
event: news
andevent: stats
appear before eachdata:
line. This is how SSE categorizes event types. - Data Payloads: We’re sending different shapes of JSON for each event type (one for “headline,” one for “activeUsers” and “sales”).
- Interval: Every 3 seconds, we send one “news” event and one “stats” event. Adjust timing to your needs.
Now, at http://localhost:3000/api/stream, you’ll see a continuous stream of SSE events labeled “news” and “stats.”
3. Consuming SSE with useEventSource
In Next.js 15, files in app/
are server components by default. We need a client component to work with browser APIs like SSE. Let’s convert our home page (page.tsx
) into a client component and use useEventSource
from react-use-websocket
.
Create or edit src/app/page.tsx
:
How useEventSource
Works
useEventSource(endpoint, options)
:endpoint
is our SSE endpoint (/api/stream
).options.events
is an object that maps named event types (news
,stats
) to callback functions.
- Named Event Handlers: If the SSE chunk has
event: news
, it calls thenews
callback; if it’sevent: stats
, it callsstats
. readyState
: 0 = CONNECTING, 1 = OPEN, 2 = CLOSED.
4. Trying It Out
- Start the dev server:
- Visit http://localhost:3000.
- Every 3 seconds, you’ll see:
- One “news” event with a random headline, appended to the “Latest Headlines” list.
- One “stats” event with random “activeUsers” and “sales,” appended to the “Stats Log.”
If you open the Network panel in your browser’s DevTools, you’ll see the continuous text/event-stream
response from /api/stream
.
5. Expanding the Example
- Multiple Frequencies: You could send “news” less often and “stats” more often by maintaining separate intervals or randomized intervals.
- Custom Event Types: Add more events, like “alerts,” “notifications,” or “chat.”
- Error Handling: If your stream requires authentication or tokens, handle them in the
options
config or query parameters.
6. Conclusion
By combining SSE with Next.js 15’s App Router and the useEventSource
hook from react-use-websocket
, you can:
- Push real-time data to connected clients with minimal overhead—no handshake complexities like WebSockets.
- Use named events (
news
,stats
, etc.) to categorize incoming data cleanly. - Easily parse JSON in your client’s callback functions for specialized updates.
Key Takeaways:
- Endpoint: A streaming
route.ts
that sends SSE data withevent: <name>
lines. - Client: A
"use client"
component withuseEventSource
, which neatly handles multiple event types. - Versatility: Perfect for live dashboards, notifications, or any scenario needing continuous one-way updates from server to client.
Experiment with authenticating requests, sending complex JSON, or hooking up a real data source for production-level streaming applications.
Damian Hodgkiss
Senior Staff Engineer at Sumo Group, leading development of AppSumo marketplace. Technical solopreneur with 25+ years of experience building SaaS products.