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: newsandevent: statsappear 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):endpointis our SSE endpoint (/api/stream).options.eventsis an object that maps named event types (news,stats) to callback functions.
- Named Event Handlers: If the SSE chunk has
event: news, it calls thenewscallback; 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
optionsconfig 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.tsthat 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.