TypeScript SDK v4 is now available! See what's new

Realtime TypeScript SDK v3

This page documents the deprecated v3 realtime API built on @inngest/realtime. For new work, use the built-in v4 realtime APIs instead: v4 realtime overview, v4 React hooks, or the v4 reference docs.

In v3, realtime support lived in the separate @inngest/realtime package and was added to your app with middleware and helper utilities. Channels and topics were defined with builders, tokens were minted on the server, and client subscriptions used either subscribe() or useInngestSubscription().

Quick start

Install the realtime package:

npm install @inngest/realtime

These docs are preserved for existing v3 apps. In v4, realtime is built into inngest and does not require a separate package.

Publishing in v3

In v3, you enabled realtime by adding realtimeMiddleware() to your client, which injected a publish() helper into your function handler.

import { Inngest } from "inngest";
import { realtimeMiddleware } from "@inngest/realtime/middleware";

export const inngest = new Inngest({
  id: "my-app",
  middleware: [realtimeMiddleware()],
});

You could publish either with raw channel and topic strings or with typed channel builders:

import { channel, topic } from "@inngest/realtime";
import { z } from "zod";

export const userChannel = channel((userId: string) => `user:${userId}`)
  .addTopic(
    topic("ai").schema(
      z.object({
        response: z.string(),
        success: z.boolean(),
      })
    )
  );

inngest.createFunction(
  { id: "create-recommendation", triggers: { event: "ai/recommendation.requested" } },
  async ({ event, publish }) => {
    await publish(
      userChannel(event.data.userId).ai({
        response: "Hello from v3 realtime",
        success: true,
      })
    );
  }
);

Subscribing in v3

The client first needed a short-lived subscription token minted on the server:

"use server";

import { getSubscriptionToken } from "@inngest/realtime";
import { inngest } from "@/inngest/client";

export async function fetchRealtimeSubscriptionToken(userId: string) {
  return getSubscriptionToken(inngest, {
    channel: `user:${userId}`,
    topics: ["ai"],
  });
}

Then the browser subscribed with useInngestSubscription() or subscribe():

"use client";

import { useInngestSubscription } from "@inngest/realtime/hooks";
import { fetchRealtimeSubscriptionToken } from "./actions";

export default function Home() {
  const { data, error } = useInngestSubscription({
    refreshToken: () => fetchRealtimeSubscriptionToken("user_123"),
  });

  if (error) {
    return <p>{error.message}</p>;
  }

  return (
    <div>
      {data.map((message, i) => (
        <div key={i}>{JSON.stringify(message.data)}</div>
      ))}
    </div>
  );
}