Skip to main content
Channels allow you to scope events to specific people or rooms. Perfect for chat rooms, realtime workspaces, or multi-tenant applications.

Basic Usage

Emit events to a specific channel:
route.ts
const channel = realtime.channel("user-123")

// 👇 emit to a specific channel:
await channel.notification.alert.emit("Hello user123!")
Subscribe to a specific channel:
page.tsx
"use client"

import { useRealtime } from "@upstash/realtime/client"
import type { RealtimeEvents } from "@/lib/realtime"

export default function Page() {
  useRealtime<RealtimeEvents>({
    // 👇 subscribe to a specific channel:
    channel: "user-123",
    events: {
      notification: {
        alert: (data) => console.log(data),
      },
    },
  })

  return <>...</>
}

Channel Patterns

Send notifications to individual users:
route.ts
await realtime.channel(`user-${userId}`).notification.alert.emit("You have a new message")
page.tsx
useRealtime<RealtimeEvents>({
  channel: `user-${currentUser.id}`,
  events: { /* ... */ },
})
Broadcast to all users in a room:
route.ts
await realtime.channel(`room-${roomId}`).message.new.emit({
  text: "Hello everyone!",
  sender: "Alice"
})
Scope events to team workspaces:
route.ts
await realtime.channel(`team-${teamId}`).update.project.emit({
  project: "Website Redesign",
  status: "In Progress"
})

Dynamic Channels

Switch channels dynamically based on user navigation:
page.tsx
"use client"

import { useState } from "react"
import { useRealtime } from "@upstash/realtime/client"

export default function Page() {
  const [roomId, setRoomId] = useState("lobby")

  useRealtime<RealtimeEvents>({
    channel: roomId,
    events: {
      chat: {
        message: (data) => console.log(`[${roomId}]`, data),
      },
    },
  })

  return (
    <div>
      <button onClick={() => setRoomId("lobby")}>Join Lobby</button>
      <button onClick={() => setRoomId("room-1")}>Join Room 1</button>
    </div>
  )
}

Broadcasting to Multiple Channels

Emit to multiple channels simultaneously:
route.ts
const channels = ["room-1", "room-2", "room-3"]

await Promise.all(
  channels.map((c) => {
    const channel = realtime.channel(c)
    await channel.announcement.broadcast.emit(`Hi channel ${channelName}!`)
  })
)

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, channel }) => {
    const user = await currentUser(request)

    if (!user.canAccessChannel(channel)) {
      return new Response("Unauthorized", { status: 401 })
    }
  },
})

Authenticate Realtime Requests

See the middleware documentation for authentication examples