> ## Documentation Index
> Fetch the complete documentation index at: https://trigger-fix-dequeue-snapshot-batch-ids.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Realtime hooks

> Get live updates from the Trigger.dev API in your frontend application.

These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). Before reading this guide:

* Read our [Realtime documentation](/realtime) to understand how the Trigger.dev realtime API works.
* Read how to [setup and authenticate](/frontend/overview) using the `@trigger.dev/react-hooks` package.

## Hooks

### useRealtimeRun

The `useRealtimeRun` hook allows you to subscribe to a run by its ID.

```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks

import { useRealtimeRun } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, error } = useRealtimeRun(runId, {
    accessToken: publicAccessToken,
  });

  if (error) return <div>Error: {error.message}</div>;

  return <div>Run: {run.id}</div>;
}
```

To correctly type the run's payload and output, you can provide the type of your task to the `useRealtimeRun` hook:

```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";
import type { myTask } from "@/trigger/myTask";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, error } = useRealtimeRun<typeof myTask>(runId, {
    accessToken: publicAccessToken,
  });

  if (error) return <div>Error: {error.message}</div>;

  // Now run.payload and run.output are correctly typed

  return <div>Run: {run.id}</div>;
}
```

You can supply an `onComplete` callback to the `useRealtimeRun` hook to be called when the run is completed or errored. This is useful if you want to perform some action when the run is completed, like navigating to a different page or showing a notification.

```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, error } = useRealtimeRun(runId, {
    accessToken: publicAccessToken,
    onComplete: (run, error) => {
      console.log("Run completed", run);
    },
  });

  if (error) return <div>Error: {error.message}</div>;

  return <div>Run: {run.id}</div>;
}
```

See our [Realtime documentation](/realtime) for more information about the type of the run object and more.

### useRealtimeRunsWithTag

The `useRealtimeRunsWithTag` hook allows you to subscribe to multiple runs with a specific tag.

```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks

import { useRealtimeRunsWithTag } from "@trigger.dev/react-hooks";

export function MyComponent({ tag }: { tag: string }) {
  const { runs, error } = useRealtimeRunsWithTag(tag);

  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {runs.map((run) => (
        <div key={run.id}>Run: {run.id}</div>
      ))}
    </div>
  );
}
```

To correctly type the runs payload and output, you can provide the type of your task to the `useRealtimeRunsWithTag` hook:

```tsx
import { useRealtimeRunsWithTag } from "@trigger.dev/react-hooks";
import type { myTask } from "@/trigger/myTask";

export function MyComponent({ tag }: { tag: string }) {
  const { runs, error } = useRealtimeRunsWithTag<typeof myTask>(tag);

  if (error) return <div>Error: {error.message}</div>;

  // Now runs[i].payload and runs[i].output are correctly typed

  return (
    <div>
      {runs.map((run) => (
        <div key={run.id}>Run: {run.id}</div>
      ))}
    </div>
  );
}
```

If `useRealtimeRunsWithTag` could return multiple different types of tasks, you can pass a union of all the task types to the hook:

```tsx
import { useRealtimeRunsWithTag } from "@trigger.dev/react-hooks";
import type { myTask1, myTask2 } from "@/trigger/myTasks";

export function MyComponent({ tag }: { tag: string }) {
  const { runs, error } = useRealtimeRunsWithTag<typeof myTask1 | typeof myTask2>(tag);

  if (error) return <div>Error: {error.message}</div>;

  // You can narrow down the type of the run based on the taskIdentifier
  for (const run of runs) {
    if (run.taskIdentifier === "my-task-1") {
      // run is correctly typed as myTask1
    } else if (run.taskIdentifier === "my-task-2") {
      // run is correctly typed as myTask2
    }
  }

  return (
    <div>
      {runs.map((run) => (
        <div key={run.id}>Run: {run.id}</div>
      ))}
    </div>
  );
}
```

### useRealtimeBatch

The `useRealtimeBatch` hook allows you to subscribe to a batch of runs by its the batch ID.

```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks

import { useRealtimeBatch } from "@trigger.dev/react-hooks";

export function MyComponent({ batchId }: { batchId: string }) {
  const { runs, error } = useRealtimeBatch(batchId);

  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {runs.map((run) => (
        <div key={run.id}>Run: {run.id}</div>
      ))}
    </div>
  );
}
```

See our [Realtime documentation](/realtime) for more information.

### useRealtimeRunWithStreams

The `useRealtimeRunWithStreams` hook allows you to subscribe to a run by its ID and also receive any streams that are emitted by the task. See our [Realtime documentation](/realtime#streams) for more information about emitting streams from a task.

```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks

import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, streams, error } = useRealtimeRunWithStreams(runId, {
    accessToken: publicAccessToken,
  });

  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <div>Run: {run.id}</div>
      <div>
        {Object.keys(streams).map((stream) => (
          <div key={stream}>Stream: {stream}</div>
        ))}
      </div>
    </div>
  );
}
```

You can provide the type of the streams to the `useRealtimeRunWithStreams` hook:

```tsx
import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
import type { myTask } from "@/trigger/myTask";

type STREAMS = {
  openai: string; // this is the type of each "part" of the stream
};

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, streams, error } = useRealtimeRunWithStreams<typeof myTask, STREAMS>(runId, {
    accessToken: publicAccessToken,
  });

  if (error) return <div>Error: {error.message}</div>;

  const text = streams.openai?.map((part) => part).join("");

  return (
    <div>
      <div>Run: {run.id}</div>
      <div>{text}</div>
    </div>
  );
}
```

As you can see above, each stream is an array of the type you provided, keyed by the stream name. If instead of a pure text stream you have a stream of objects, you can provide the type of the object:

```tsx
import type { TextStreamPart } from "ai";
import type { myTask } from "@/trigger/myTask";

type STREAMS = { openai: TextStreamPart<{}> };

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, streams, error } = useRealtimeRunWithStreams<typeof myTask, STREAMS>(runId, {
    accessToken: publicAccessToken,
  });

  if (error) return <div>Error: {error.message}</div>;

  const text = streams.openai
    ?.filter((stream) => stream.type === "text-delta")
    ?.map((part) => part.text)
    .join("");

  return (
    <div>
      <div>Run: {run.id}</div>
      <div>{text}</div>
    </div>
  );
}
```

## Common options

### accessToken & baseURL

You can pass the `accessToken` option to the Realtime hooks to authenticate the subscription.

```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { run, error } = useRealtimeRun(runId, {
    accessToken: publicAccessToken,
    baseURL: "https://my-self-hosted-trigger.com", // Optional if you are using a self-hosted Trigger.dev instance
  });

  if (error) return <div>Error: {error.message}</div>;

  return <div>Run: {run.id}</div>;
}
```

### enabled

You can pass the `enabled` option to the Realtime hooks to enable or disable the subscription.

```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
  enabled,
}: {
  runId: string;
  publicAccessToken: string;
  enabled: boolean;
}) {
  const { run, error } = useRealtimeRun(runId, {
    accessToken: publicAccessToken,
    enabled,
  });

  if (error) return <div>Error: {error.message}</div>;

  return <div>Run: {run.id}</div>;
}
```

This allows you to conditionally disable using the hook based on some state.

### id

You can pass the `id` option to the Realtime hooks to change the ID of the subscription.

```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";

export function MyComponent({
  id,
  runId,
  publicAccessToken,
  enabled,
}: {
  id: string;
  runId: string;
  publicAccessToken: string;
  enabled: boolean;
}) {
  const { run, error } = useRealtimeRun(runId, {
    accessToken: publicAccessToken,
    enabled,
    id,
  });

  if (error) return <div>Error: {error.message}</div>;

  return <div>Run: {run.id}</div>;
}
```

This allows you to change the ID of the subscription based on some state. Passing in a different ID will unsubscribe from the current subscription and subscribe to the new one (and remove any cached data).

### experimental\_throttleInMs

The `*withStreams` variants of the Realtime hooks accept an `experimental_throttleInMs` option to throttle the updates from the server. This can be useful if you are getting too many updates and want to reduce the number of updates.

```tsx
import { useRealtimeRunsWithStreams } from "@trigger.dev/react-hooks";

export function MyComponent({
  runId,
  publicAccessToken,
}: {
  runId: string;
  publicAccessToken: string;
}) {
  const { runs, error } = useRealtimeRunsWithStreams(tag, {
    accessToken: publicAccessToken,
    experimental_throttleInMs: 1000, // Throttle updates to once per second
  });

  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {runs.map((run) => (
        <div key={run.id}>Run: {run.id}</div>
      ))}
    </div>
  );
}
```

## Examples

<CardGroup cols={2}>
  <Card title="Image Generation with fal.ai" icon="image" href="/guides/example-projects/realtime-fal-ai">
    A Next.js app that uses the Realtime API and react hooks to create on-demand image generation
    through fal.ai's services.
  </Card>

  <Card title="Realtime CSV Importer" icon="file-csv" href="/guides/example-projects/realtime-csv-importer">
    Upload CSV files and view the progress of the task being processed on the frontend live using
    the Realtime API.
  </Card>

  <Card title="Batch LLM Evaluator" icon="sparkles" href="/guides/example-projects/batch-llm-evaluator">
    A Next.js app that uses the Realtime API and react hooks to evaluate language model responses on
    the frontend in real-time.
  </Card>

  <Card title="Claude Thinking Chatbot" icon="messages" href="/guides/example-projects/claude-thinking-chatbot">
    A chatbot that demonstrates Claude 3.7's thinking capabilities through the Realtime API and
    react hooks.
  </Card>
</CardGroup>

### Learn more

<CardGroup cols={2}>
  <Card title="View all our guides & examples" icon="books" href="/guides">
    Guides, example projects and example tasks. Copy any of the code and use it in your own
    projects.
  </Card>

  <Card title="Example projects repo" icon="github" href="https://github.com/triggerdotdev/examples">
    Star/Fork our examples repo to learn more about how to use Trigger.dev in full stack
    applications.
  </Card>
</CardGroup>
