react-eventsource
v2.1.0
Published
React hook for Server-Sent Events with custom headers support, built on @microsoft/fetch-event-source
Downloads
219
Readme
React EventSource
React hook for Server-Sent Events with custom headers support
A simple React hook for Server-Sent Events with the key feature that native EventSource lacks: custom headers support.
Perfect for authenticated Server-Sent Events, API keys, and any scenario where you need to send headers with your SSE connection.
Installation
npm install react-eventsourceQuick Start
import React from 'react'
import { useSSE } from 'react-eventsource'
function ServerUpdates() {
const { readyState, close, reconnect } = useSSE({
url: '/api/events',
headers: {
'Authorization': 'Bearer your-token',
'X-API-Key': 'your-api-key'
},
onMessage: (message) => {
console.log('Received:', message.data)
},
onError: (error) => {
console.error('SSE Error:', error)
}
})
const status = ['CONNECTING', 'OPEN', 'CLOSED'][readyState]
return (
<div>
<p>Connection: {status}</p>
<button onClick={close}>Close</button>
<button onClick={reconnect}>Reconnect</button>
</div>
)
}API Reference
useSSE(options)
Options
| Property | Type | Required | Description |
|------------------|-------------------------------------------|----------|-----------------------------------------------------------------------|
| url | string | Yes | Server-Sent Events endpoint URL |
| headers | Record<string, string> | No | Custom headers (auth, API keys, etc.) |
| method | string | No | HTTP method (defaults to 'GET') |
| body | string \| FormData | No | Request body (rarely needed for SSE) |
| onMessage | (message: EventSourceMessage) => void | No | Message event handler |
| onOpen | (response: Response) => void | No | Connection open handler |
| onError | (error: unknown) => void | No | Error handler |
| fetch | typeof window.fetch | No | Custom fetch implementation |
| openWhenHidden | boolean | No | Keep connection open when page is hidden (defaults to true) |
Return Values
| Property | Type | Description |
|--------------|--------------|--------------------------------------------------------|
| readyState | number | Connection state: 0=CONNECTING, 1=OPEN, 2=CLOSED |
| close | () => void | Manually close the connection |
| reconnect | () => void | Close current connection and immediately reconnect |
TypeScript Support
The hook is fully typed and exports the following types:
import { useSSE, type UseSSEOptions, type UseSSEResult } from 'react-eventsource'
// Type your own variables
const config: UseSSEOptions = {
url: '/api/events',
headers: { 'Authorization': 'Bearer token' }
}
// Extend the interface if needed
interface MySSEOptions extends UseSSEOptions {
retryCount?: number
}Examples
Authenticated Events
useSSE({
url: '/api/user-notifications',
headers: {
'Authorization': `Bearer ${userToken}`
},
onMessage: (msg) => {
const notification = JSON.parse(msg.data)
showNotification(notification)
}
})POST with Body (Advanced)
useSSE({
url: '/api/stream',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-User-ID': userId
},
body: JSON.stringify({
channels: ['updates', 'alerts']
}),
onMessage: handleStreamMessage
})Connection Management
function ChatStream() {
const { readyState, close, reconnect } = useSSE({
url: '/api/chat-stream',
headers: { 'Authorization': `Bearer ${token}` },
onMessage: (msg) => addMessage(JSON.parse(msg.data)),
onError: (err) => console.error('Chat stream error:', err)
})
const isConnected = readyState === 1
return (
<div>
<div className={`status ${isConnected ? 'connected' : 'disconnected'}`}>
{isConnected ? '🟢 Connected' : '🔴 Disconnected'}
</div>
<button onClick={reconnect} disabled={readyState === 0}>
Reconnect
</button>
<button onClick={close}>
Disconnect
</button>
</div>
)
}Page Visibility Behavior
By default, this hook keeps SSE connections open even when the browser tab/window is hidden (minimized, switched away, etc.). This matches the behavior of the native EventSource API.
If you want to close the connection when the page is hidden and automatically reconnect when visible again (to reduce server load), set openWhenHidden to false:
useSSE({
url: '/api/events',
openWhenHidden: false, // Close connection when page is hidden
onMessage: (msg) => console.log(msg.data)
})When to use openWhenHidden: false:
- You want to reduce server load by closing idle connections
- Your app doesn't need real-time updates when the user isn't viewing the page
- You're implementing a background sync that should pause when hidden
When to keep the default (true):
- You need continuous updates regardless of page visibility
- You're building a real-time monitoring dashboard
- Missing events while hidden would cause data inconsistency
Why This Hook?
- Native EventSource limitation: Cannot send custom headers
- This hook solves that: Built on
@microsoft/fetch-event-sourcewhich supports headers - React-friendly: Manages connection lifecycle with useEffect
- Simple API: Familiar EventSource-like interface
- TypeScript: Full type safety out of the box
License
MIT License. See LICENSE for details.
