### Initialize Realtime Instance Source: https://context7.com/upstash/realtime/llms.txt Configure the Realtime instance with Redis, Zod schemas for type safety, and optional history settings. ```typescript import { Realtime } from "@upstash/realtime"; import { Redis } from "@upstash/redis"; import { z } from "zod"; // Define your event schema with Zod for type-safe events const schema = { message: z.object({ text: z.string(), userId: z.string(), }), notification: z.object({ title: z.string(), body: z.string(), }), // Nested schemas for organizing events user: { joined: z.object({ userId: z.string(), name: z.string() }), left: z.object({ userId: z.string() }), }, }; // Create the Realtime instance const realtime = new Realtime({ redis: Redis.fromEnv(), schema, maxDurationSecs: 300, // Connection timeout (default: 300s for Vercel) verbose: true, // Enable logging history: { maxLength: 1000, // Maximum messages to retain per channel expireAfterSecs: 86400, // Expire history after 24 hours }, }); export { realtime }; ``` -------------------------------- ### Set Up RealtimeProvider in React Layout Source: https://context7.com/upstash/realtime/llms.txt Wrap your React application with `RealtimeProvider` to enable realtime subscriptions globally. Configure the SSE endpoint URL and connection options like `withCredentials` and `maxReconnectAttempts`. ```tsx // app/layout.tsx or _app.tsx "use client"; import { RealtimeProvider } from "@upstash/realtime/client"; export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Create a Typed Realtime Client with Event Schema Source: https://context7.com/upstash/realtime/llms.txt Define a shared event schema using `createRealtime` to ensure type safety across your application. This factory creates a `useRealtime` hook with inferred types for events and data. ```typescript // lib/realtime-client.ts "use client"; import { createRealtime } from "@upstash/realtime/client"; // Define your event schema (should match server-side schema) type RealtimeEvents = { message: { text: string; userId: string }; notification: { title: string; body: string }; user: { joined: { userId: string; name: string }; left: { userId: string }; }; }; export const { useRealtime } = createRealtime(); // Usage in components with full type inference // components/NotificationBell.tsx "use client"; import { useRealtime } from "@/lib/realtime-client"; export function NotificationBell() { const { status } = useRealtime({ channels: ["notifications"], events: ["notification"] as const, onData: (event) => { // event.data is typed as { title: string; body: string } showToast(event.data.title, event.data.body); }, }); return ; } ``` -------------------------------- ### Create SSE Request Handler with Middleware Source: https://context7.com/upstash/realtime/llms.txt Implement an HTTP endpoint for SSE connections with optional authentication and authorization middleware. The middleware validates tokens and checks channel permissions before allowing a connection. ```typescript // app/api/realtime/route.ts (Next.js App Router) import { handle } from "@upstash/realtime"; import { realtime } from "@/lib/realtime"; const handler = handle({ realtime, // Optional authentication middleware middleware: async ({ request, channels }) => { const authHeader = request.headers.get("authorization"); if (!authHeader) { return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" }, }); } // Validate token and check channel permissions const userId = await validateToken(authHeader); const allowedChannels = await getUserChannels(userId); for (const channel of channels) { if (!allowedChannels.includes(channel)) { return new Response(JSON.stringify({ error: "Forbidden" }), { status: 403, headers: { "Content-Type": "application/json" }, }); } } // Return undefined to allow the connection return undefined; }, }); export async function GET(request: Request) { return handler(request); } ``` -------------------------------- ### Subscribe to Events Source: https://context7.com/upstash/realtime/llms.txt Listen for specific events on a channel and optionally replay historical messages upon subscription. ```typescript import { realtime } from "./realtime"; // Subscribe to specific events on a channel const unsubscribe = await realtime.channel("chat-room-1").subscribe({ events: ["message", "user.joined"] as const, onData: (event) => { console.log(`Received ${event.event}:`, event.data); // event.event is typed as "message" | "user.joined" // event.data is typed based on the schema }, // Optionally replay history on subscribe history: { limit: 100, // Get last 100 messages }, }); // Unsubscribe when done unsubscribe(); ``` -------------------------------- ### Subscribe to Events Source: https://context7.com/upstash/realtime/llms.txt Subscribe to specific events on a channel to receive real-time updates or replay historical messages. ```APIDOC ## POST /subscribe ### Description Registers a listener for specific events on a channel. Supports optional history replay upon subscription. ### Parameters #### Request Body - **events** (array) - Required - List of event names to subscribe to. - **onData** (function) - Required - Callback function executed when an event is received. - **history** (object) - Optional - Configuration for replaying past messages. - **limit** (number) - Optional - Number of historical messages to retrieve. ### Request Example { "events": ["message", "user.joined"], "history": { "limit": 100 } } ``` -------------------------------- ### Emit Realtime Events Source: https://context7.com/upstash/realtime/llms.txt Send type-safe events to default or specific channels using the emit method. ```typescript import { realtime } from "./realtime"; // Emit to default channel await realtime.emit("message", { text: "Hello, World!", userId: "user-123", }); // Emit to a specific channel await realtime.channel("chat-room-1").emit("message", { text: "Welcome to the chat!", userId: "admin", }); // Emit nested events await realtime.channel("lobby").emit("user.joined", { userId: "user-456", name: "Alice", }); ``` -------------------------------- ### Emit Events Source: https://context7.com/upstash/realtime/llms.txt The emit method sends type-safe events to channels, persisting them to Redis Streams and broadcasting to subscribers. ```APIDOC ## POST /emit ### Description Sends a type-safe event to a specified channel or the default channel. Events are persisted to Redis Streams. ### Parameters #### Request Body - **event** (string) - Required - The name of the event defined in the schema. - **data** (object) - Required - The payload matching the schema definition for the event. ### Request Example { "event": "message", "data": { "text": "Hello, World!", "userId": "user-123" } } ``` -------------------------------- ### Access Realtime Context Directly with useRealtimeContext Source: https://context7.com/upstash/realtime/llms.txt Use `useRealtimeContext` to access the realtime connection status directly within any component. This is useful for displaying connection indicators or managing subscriptions manually. ```tsx "use client"; import { useRealtimeContext } from "@upstash/realtime/client"; export function ConnectionIndicator() { const { status } = useRealtimeContext(); return (
{status}
); } ``` -------------------------------- ### Subscribe to Realtime Events with useRealtime Hook Source: https://context7.com/upstash/realtime/llms.txt Use the `useRealtime` hook within React components to subscribe to specific channels and events. It provides connection status and handles incoming data with automatic connection management. ```tsx "use client"; import { useRealtime } from "@upstash/realtime/client"; import { useState } from "react"; type Message = { text: string; userId: string; }; export function ChatRoom({ roomId }: { roomId: string }) { const [messages, setMessages] = useState([]); const { status } = useRealtime<{ message: Message; "user.joined": { userId: string; name: string }; }>({ channels: [roomId], // Subscribe to specific channel events: ["message", "user.joined"] as const, enabled: true, // Can be toggled to enable/disable onData: (event) => { if (event.event === "message") { setMessages((prev) => [...prev, event.data]); } else if (event.event === "user.joined") { console.log(`${event.data.name} joined the chat`); } }, }); return (
Connection Status: {status}
{/* status: "connected" | "connecting" | "disconnected" | "error" */}
    {messages.map((msg, i) => (
  • {msg.text}
  • ))}
); } ``` -------------------------------- ### Retrieve Message History Source: https://context7.com/upstash/realtime/llms.txt Fetch historical messages from Redis Streams, supporting filtering by time range and result limits. ```typescript import { realtime } from "./realtime"; // Get history from default channel const messages = await realtime.history({ limit: 50, // Max 1000 }); // Get history from specific channel with time range const channelHistory = await realtime.channel("chat-room-1").history({ start: Date.now() - 3600000, // 1 hour ago end: Date.now(), limit: 100, }); // Each message includes: id, event, channel, data messages.forEach((msg) => { console.log(`[${msg.id}] ${msg.event}: ${JSON.stringify(msg.data)}`); }); ``` -------------------------------- ### Retrieve Message History Source: https://context7.com/upstash/realtime/llms.txt Fetch historical messages from Redis Streams for a specific channel or the default channel. ```APIDOC ## GET /history ### Description Retrieves historical messages from Redis Streams with optional filtering by time range and limit. ### Parameters #### Query Parameters - **start** (number) - Optional - Start timestamp for history retrieval. - **end** (number) - Optional - End timestamp for history retrieval. - **limit** (number) - Optional - Maximum number of messages to return (max 1000). ### Response #### Success Response (200) - **messages** (array) - List of message objects containing id, event, channel, and data. #### Response Example [ { "id": "1715678900000-0", "event": "message", "channel": "chat-room-1", "data": { "text": "Hello", "userId": "user-1" } } ] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.