Documentation Index
Fetch the complete documentation index at: https://upstash.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Channels allow you to scope events to specific people or rooms. For example:
- Chat rooms
- Emitting events to a specific user
Default Channel
By default, events are sent to the default channel. If we emit an event without specifying a channel like so:
await realtime.emit("notification.alert", "hello world!")
it can automatically be read using the default channel:
useRealtime({
events: ["notification.alert"],
onData({ event, data, channel }) {
console.log(data)
},
})
Custom Channels
Emit events to a specific channel:
const channel = realtime.channel("user-123")
await channel.emit("notification.alert", "hello world!")
Subscribe to one or more channels:
"use client"
import { useRealtime } from "@/lib/realtime-client"
export default function Page() {
useRealtime({
channels: ["user-123"],
events: ["notification.alert"],
onData({ event, data, channel }) {
console.log(data)
},
})
return <>...</>
}
Channel Patterns
Send notifications to individual users:const channel = realtime.channel(`user-${userId}`)
await channel.emit("notification.alert", "hello world!")
useRealtime({
channels: [`user-${user.id}`],
events: ["notification.alert"],
onData({ data }) {},
})
Broadcast to all users in a room:await realtime.channel(`room-${roomId}`).emit("room.message", {
text: "Hello everyone!",
sender: "Alice",
})
Scope events to team workspaces:await realtime.channel(`team-${teamId}`).emit("project.update", {
project: "Website Redesign",
status: "In Progress",
})
Dynamic Channels
Subscribe to multiple channels at the same time:
"use client"
import { useState } from "react"
import { useRealtime } from "@/lib/realtime-client"
export default function Page() {
const [channels, setChannels] = useState<string[]>(["lobby"])
useRealtime({
channels,
events: ["chat.message"],
onData({ event, data, channel }) {
console.log(`Message from ${channel}:`, data)
},
})
const joinRoom = (roomId: string) => {
setChannels((prev) => [...prev, roomId])
}
const leaveRoom = (roomId: string) => {
setChannels((prev) => prev.filter((c) => c !== roomId))
}
return (
<div>
<p>Active channels: {channels.join(", ")}</p>
<button onClick={() => joinRoom("room-1")}>Join Room 1</button>
<button onClick={() => joinRoom("room-2")}>Join Room 2</button>
<button onClick={() => leaveRoom("lobby")}>Leave Lobby</button>
</div>
)
}
Broadcasting to Multiple Channels
Emit to multiple channels at the same time:
const rooms = ["lobby", "room-1", "room-2"]
await Promise.all(
rooms.map((room) => {
const channel = realtime.channel(room)
return channel.emit("chat.message", `Hi channel ${room}!`)
})
)
Channel Security
Combine channels with middleware for secure access control:
app/api/realtime/route.ts
import { handle } from "@upstash/realtime"
import { realtime } from "@/lib/realtime"
import { currentUser } from "@/auth"
export const GET = handle({
realtime,
middleware: async ({ request, channels }) => {
const user = await currentUser(request)
for (const channel of channels) {
if (!user.canAccessChannel(channel)) {
return new Response("Unauthorized", { status: 401 })
}
}
},
})
Authenticate Realtime Requests
See the middleware documentation for authentication examples