From d17fe9d97a99f19efdc5249138558db802cd624f Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:03:00 +0100
Subject: [PATCH 01/27] Reordered react hooks + frontend sections
---
docs/docs.json | 79 +++-
.../overview.mdx => realtime/auth.mdx} | 92 ++++-
docs/realtime/backend/metadata.mdx | 225 +++++++++++
docs/realtime/backend/overview.mdx | 63 ++++
docs/realtime/{ => backend}/streams.mdx | 160 ++------
docs/realtime/backend/subscribe.mdx | 116 ++++++
docs/realtime/how-it-works.mdx | 91 +++++
docs/realtime/overview.mdx | 282 ++------------
docs/realtime/react-hooks.mdx | 7 -
docs/realtime/react-hooks/metadata.mdx | 357 ++++++++++++++++++
.../react-hooks/overview.mdx | 35 +-
.../react-hooks/realtime.mdx | 141 +------
docs/realtime/react-hooks/streams.mdx | 225 +++++++++++
.../react-hooks/triggering.mdx | 28 +-
docs/realtime/run-object.mdx | 142 +++++++
docs/realtime/subscribe-to-batch.mdx | 49 ---
docs/realtime/subscribe-to-run.mdx | 49 ---
docs/realtime/subscribe-to-runs-with-tag.mdx | 49 ---
18 files changed, 1458 insertions(+), 732 deletions(-)
rename docs/{frontend/overview.mdx => realtime/auth.mdx} (64%)
create mode 100644 docs/realtime/backend/metadata.mdx
create mode 100644 docs/realtime/backend/overview.mdx
rename docs/realtime/{ => backend}/streams.mdx (60%)
create mode 100644 docs/realtime/backend/subscribe.mdx
create mode 100644 docs/realtime/how-it-works.mdx
delete mode 100644 docs/realtime/react-hooks.mdx
create mode 100644 docs/realtime/react-hooks/metadata.mdx
rename docs/{frontend => realtime}/react-hooks/overview.mdx (88%)
rename docs/{frontend => realtime}/react-hooks/realtime.mdx (65%)
create mode 100644 docs/realtime/react-hooks/streams.mdx
rename docs/{frontend => realtime}/react-hooks/triggering.mdx (92%)
create mode 100644 docs/realtime/run-object.mdx
delete mode 100644 docs/realtime/subscribe-to-batch.mdx
delete mode 100644 docs/realtime/subscribe-to-run.mdx
delete mode 100644 docs/realtime/subscribe-to-runs-with-tag.mdx
diff --git a/docs/docs.json b/docs/docs.json
index b88d903a93..12b1565064 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -112,30 +112,33 @@
]
},
{
- "group": "Frontend usage",
+ "group": "Realtime",
"pages": [
- "frontend/overview",
+ "realtime/overview",
+ "realtime/how-it-works",
+ "realtime/run-object",
+ "realtime/auth",
+ {
+ "group": "React hooks (frontend)",
+ "pages": [
+ "realtime/react-hooks/overview",
+ "realtime/react-hooks/realtime",
+ "realtime/react-hooks/metadata",
+ "realtime/react-hooks/streams",
+ "realtime/react-hooks/triggering"
+ ]
+ },
{
- "group": "React hooks",
+ "group": "Backend",
"pages": [
- "frontend/react-hooks/overview",
- "frontend/react-hooks/realtime",
- "frontend/react-hooks/triggering"
+ "realtime/backend/overview",
+ "realtime/backend/subscribe",
+ "realtime/backend/metadata",
+ "realtime/backend/streams"
]
}
]
},
- {
- "group": "Realtime API",
- "pages": [
- "realtime/overview",
- "realtime/streams",
- "realtime/react-hooks",
- "realtime/subscribe-to-run",
- "realtime/subscribe-to-runs-with-tag",
- "realtime/subscribe-to-batch"
- ]
- },
{
"group": "CLI",
"pages": [
@@ -570,7 +573,47 @@
},
{
"source": "/frontend/react-hooks",
- "destination": "/frontend/react-hooks/overview"
+ "destination": "/realtime/react-hooks/overview"
+ },
+ {
+ "source": "/frontend/overview",
+ "destination": "/realtime/auth"
+ },
+ {
+ "source": "/frontend/react-hooks/overview",
+ "destination": "/realtime/react-hooks/overview"
+ },
+ {
+ "source": "/frontend/react-hooks/realtime",
+ "destination": "/realtime/react-hooks/realtime"
+ },
+ {
+ "source": "/frontend/react-hooks/triggering",
+ "destination": "/realtime/react-hooks/triggering"
+ },
+ {
+ "source": "/realtime/backend",
+ "destination": "/realtime/backend/overview"
+ },
+ {
+ "source": "/realtime/streams",
+ "destination": "/realtime/backend/streams"
+ },
+ {
+ "source": "/realtime/react-hooks",
+ "destination": "/realtime/react-hooks/overview"
+ },
+ {
+ "source": "/realtime/subscribe-to-run",
+ "destination": "/realtime/backend/subscribe"
+ },
+ {
+ "source": "/realtime/subscribe-to-runs-with-tag",
+ "destination": "/realtime/backend/subscribe"
+ },
+ {
+ "source": "/realtime/subscribe-to-batch",
+ "destination": "/realtime/backend/subscribe"
},
{
"source": "/management/projects/runs",
diff --git a/docs/frontend/overview.mdx b/docs/realtime/auth.mdx
similarity index 64%
rename from docs/frontend/overview.mdx
rename to docs/realtime/auth.mdx
index 6df411bc3a..dd6af13ca8 100644
--- a/docs/frontend/overview.mdx
+++ b/docs/realtime/auth.mdx
@@ -1,14 +1,14 @@
---
-title: Overview & Authentication
-sidebarTitle: Overview & Auth
-description: Using the Trigger.dev SDK from your frontend application.
+title: Authentication
+sidebarTitle: Authentication
+description: Authenticating real-time API requests with Public Access Tokens
---
-You can use our [React hooks](/frontend/react-hooks) in your frontend application to interact with the Trigger.dev API. This guide will show you how to generate Public Access Tokens that can be used to authenticate your requests.
+To use the Realtime API, you need to authenticate your requests with Public Access Tokens. These tokens provide secure, scoped access to your runs and can be used in both frontend and backend applications.
-## Authentication
+## Creating Public Access Tokens
-To create a Public Access Token, you can use the `auth.createPublicToken` function in your **backend** code:
+You can create a Public Access Token using the `auth.createPublicToken` function in your **backend** code:
```tsx
import { auth } from "@trigger.dev/sdk/v3";
@@ -16,7 +16,7 @@ import { auth } from "@trigger.dev/sdk/v3";
const publicToken = await auth.createPublicToken(); // π this public access token has no permissions, so is pretty useless!
```
-### Scopes
+## Scopes
By default a Public Access Token has no permissions. You must specify the scopes you need when creating a Public Access Token:
@@ -103,7 +103,7 @@ const publicToken = await auth.createPublicToken({
});
```
-### Expiration
+## Expiration
By default, Public Access Token's expire after 15 minutes. You can specify a different expiration time when creating a Public Access Token:
@@ -166,6 +166,78 @@ const handle = await tasks.batchTrigger("my-task", [
console.log(handle.publicAccessToken);
```
-## Usage
+## Trigger tokens
-To learn how to use these Public Access Tokens, see our [React hooks](/frontend/react-hooks) guide.
+For triggering tasks from your frontend, you need special "trigger" tokens. These tokens can only be used once to trigger a task and are more secure than regular Public Access Tokens.
+
+```ts
+import { auth } from "@trigger.dev/sdk/v3";
+
+// Somewhere in your backend code
+const triggerToken = await auth.createTriggerPublicToken("my-task");
+```
+
+These tokens also expire, with the default expiration time being 15 minutes. You can specify a custom expiration time:
+
+```ts
+import { auth } from "@trigger.dev/sdk/v3";
+
+// Somewhere in your backend code
+const triggerToken = await auth.createTriggerPublicToken("my-task", {
+ expirationTime: "24hr",
+});
+```
+
+You can pass multiple tasks to create a token that can trigger multiple tasks:
+
+```ts
+import { auth } from "@trigger.dev/sdk/v3";
+
+// Somewhere in your backend code
+const triggerToken = await auth.createTriggerPublicToken(["my-task-1", "my-task-2"]);
+```
+
+You can also create tokens that can be used multiple times:
+
+```ts
+import { auth } from "@trigger.dev/sdk/v3";
+
+// Somewhere in your backend code
+const triggerToken = await auth.createTriggerPublicToken("my-task", {
+ multipleUse: true, // β Use this with caution!
+});
+```
+
+## Using tokens
+
+Once you have a Public Access Token, you can use it to authenticate requests to the Realtime API:
+
+### Backend usage
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+
+// Using the token with backend functions
+for await (const run of runs.subscribeToRun("run_1234", {
+ accessToken: publicToken,
+})) {
+ console.log(run);
+}
+```
+
+### Frontend usage
+
+```tsx
+import { useRealtimeRun } from "@trigger.dev/react-hooks";
+
+export function MyComponent({ runId, publicAccessToken }) {
+ const { run, error } = useRealtimeRun(runId, {
+ accessToken: publicAccessToken,
+ });
+
+ if (error) return
Error: {error.message}
;
+ return
Run: {run?.id}
;
+}
+```
+
+See our [React hooks documentation](/realtime/react-hooks) for more details on using hooks in your frontend application.
diff --git a/docs/realtime/backend/metadata.mdx b/docs/realtime/backend/metadata.mdx
new file mode 100644
index 0000000000..7c35d6f4bf
--- /dev/null
+++ b/docs/realtime/backend/metadata.mdx
@@ -0,0 +1,225 @@
+---
+title: Metadata
+sidebarTitle: Metadata
+description: Update and subscribe to run metadata in real-time from your backend
+---
+
+import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
+
+The metadata API allows you to update custom metadata on runs and receive real-time updates when metadata changes. This is useful for tracking progress, storing intermediate results, or adding custom status information that can be monitored in real-time.
+
+
+ For frontend applications using React, see our [React hooks metadata
+ documentation](/realtime/react-hooks/metadata) for consuming metadata updates in your UI.
+
+
+## How metadata works with realtime
+
+When you update metadata from within a task using `metadata.set()`, `metadata.append()`, or other metadata methods, all subscribers to that run will automatically receive the updated run object containing the new metadata.
+
+This makes metadata perfect for:
+
+- Progress tracking
+- Status updates
+- Intermediate results
+- Custom notifications
+
+## Updating metadata from tasks
+
+Use the metadata API within your task to update metadata in real-time:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const progressTask = task({
+ id: "progress-task",
+ run: async (payload: { items: string[] }) => {
+ const total = payload.items.length;
+
+ for (let i = 0; i < payload.items.length; i++) {
+ // Update progress metadata
+ metadata.set("progress", {
+ current: i + 1,
+ total: total,
+ percentage: Math.round(((i + 1) / total) * 100),
+ currentItem: payload.items[i],
+ });
+
+ // Process the item
+ await processItem(payload.items[i]);
+ }
+
+ metadata.set("status", "completed");
+ return { processed: total };
+ },
+});
+
+async function processItem(item: string) {
+ // Simulate work
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+}
+```
+
+## Subscribing to metadata updates
+
+Subscribe to runs and receive real-time metadata updates:
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { progressTask } from "./trigger/progress-task";
+
+async function monitorProgress(runId: string) {
+ for await (const run of runs.subscribeToRun(runId)) {
+ console.log(`Run ${run.id} status: ${run.status}`);
+
+ if (run.metadata?.progress) {
+ const progress = run.metadata.progress as {
+ current: number;
+ total: number;
+ percentage: number;
+ currentItem: string;
+ };
+
+ console.log(`Progress: ${progress.current}/${progress.total} (${progress.percentage}%)`);
+ console.log(`Processing: ${progress.currentItem}`);
+ }
+
+ if (run.metadata?.status === "completed") {
+ console.log("Task completed!");
+ break;
+ }
+ }
+}
+```
+
+## Common metadata patterns
+
+### Progress tracking
+
+Track progress with percentage and current step:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const batchProcessingTask = task({
+ id: "batch-processing",
+ run: async (payload: { records: any[] }) => {
+ for (let i = 0; i < payload.records.length; i++) {
+ const record = payload.records[i];
+
+ // Update progress
+ metadata.set("progress", {
+ step: i + 1,
+ total: payload.records.length,
+ percentage: Math.round(((i + 1) / payload.records.length) * 100),
+ currentRecord: record.id,
+ });
+
+ await processRecord(record);
+ }
+ },
+});
+```
+
+### Status updates with logs
+
+Append log entries while maintaining status:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const deploymentTask = task({
+ id: "deployment",
+ run: async (payload: { version: string }) => {
+ metadata.set("status", "initializing");
+ metadata.append("logs", "Starting deployment...");
+
+ // Step 1
+ metadata.set("status", "building");
+ metadata.append("logs", "Building application...");
+ await buildApplication();
+
+ // Step 2
+ metadata.set("status", "deploying");
+ metadata.append("logs", "Deploying to production...");
+ await deployToProduction();
+
+ // Step 3
+ metadata.set("status", "verifying");
+ metadata.append("logs", "Running health checks...");
+ await runHealthChecks();
+
+ metadata.set("status", "completed");
+ metadata.append("logs", "Deployment successful!");
+ },
+});
+```
+
+### User context and notifications
+
+Store user information and notification preferences:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const userTask = task({
+ id: "user-task",
+ run: async (payload: { userId: string; action: string }) => {
+ // Set user context in metadata
+ metadata.set("user", {
+ id: payload.userId,
+ action: payload.action,
+ startedAt: new Date().toISOString(),
+ });
+
+ // Update status for user notifications
+ metadata.set("notification", {
+ type: "info",
+ message: `Starting ${payload.action} for user ${payload.userId}`,
+ });
+
+ await performUserAction(payload);
+
+ metadata.set("notification", {
+ type: "success",
+ message: `${payload.action} completed successfully`,
+ });
+ },
+});
+```
+
+## Type safety
+
+You can get type safety for your metadata by defining types:
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { progressTask } from "./trigger/progress-task";
+
+interface ProgressMetadata {
+ progress?: {
+ current: number;
+ total: number;
+ percentage: number;
+ currentItem: string;
+ };
+ status?: "running" | "completed" | "failed";
+}
+
+async function monitorTypedProgress(runId: string) {
+ for await (const run of runs.subscribeToRun(runId)) {
+ const metadata = run.metadata as ProgressMetadata;
+
+ if (metadata?.progress) {
+ // Now you have full type safety
+ console.log(`Progress: ${metadata.progress.percentage}%`);
+ }
+ }
+}
+```
+
+## Authentication
+
+Backend metadata subscriptions support both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific run, task, or tag. See our [authentication guide](/realtime/auth) for details.
+
+{" "}
diff --git a/docs/realtime/backend/overview.mdx b/docs/realtime/backend/overview.mdx
new file mode 100644
index 0000000000..931493b4c4
--- /dev/null
+++ b/docs/realtime/backend/overview.mdx
@@ -0,0 +1,63 @@
+---
+title: Backend overview
+sidebarTitle: Overview
+description: Using the Trigger.dev realtime API from your backend code
+---
+
+import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
+
+Use these backend functions to subscribe to runs and streams from your server-side code or other tasks.
+
+## Overview
+
+The backend API provides three main categories of functionality:
+
+- **[Subscribe functions](/realtime/backend/subscribe)** - Subscribe to run updates using async iterators
+- **[Metadata](/realtime/backend/metadata)** - Update and subscribe to run metadata in real-time
+- **[Streams](/realtime/backend/streams)** - Emit and consume real-time streaming data from your tasks
+
+## Quick example
+
+Subscribe to a run:
+
+```ts
+import { runs, tasks } from "@trigger.dev/sdk/v3";
+
+// Trigger a task
+const handle = await tasks.trigger("my-task", { some: "data" });
+
+// Subscribe to real-time updates
+for await (const run of runs.subscribeToRun(handle.id)) {
+ console.log(`Run ${run.id} status: ${run.status}`);
+}
+```
+
+Stream data from a task:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const myTask = task({
+ id: "my-task",
+ run: async (payload) => {
+ // Stream real-time data
+ const stream = await metadata.stream("openai", openaiCompletion);
+
+ // Process the stream
+ for await (const chunk of stream) {
+ console.log("Streaming chunk:", chunk);
+ }
+ },
+});
+```
+
+## Authentication
+
+All backend functions support both server-side and client-side authentication:
+
+- **Server-side**: Use your API key (automatically handled in tasks)
+- **Client-side**: Generate a Public Access Token with appropriate scopes
+
+See our [authentication guide](/realtime/auth) for detailed information on creating and using tokens.
+
+{" "}
diff --git a/docs/realtime/streams.mdx b/docs/realtime/backend/streams.mdx
similarity index 60%
rename from docs/realtime/streams.mdx
rename to docs/realtime/backend/streams.mdx
index aa74a68e09..a291b3ee8b 100644
--- a/docs/realtime/streams.mdx
+++ b/docs/realtime/backend/streams.mdx
@@ -1,20 +1,25 @@
---
-title: Realtime streams
+title: Streams
sidebarTitle: Streams
-description: Stream data in realtime from inside your tasks
+description: Emit and consume real-time streaming data from your tasks
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-The world is going realtime, and so should your tasks. With the Streams API, you can stream data from your tasks to the outside world in realtime. This is useful for a variety of use cases, including AI.
+The Streams API allows you to stream data from your tasks to the outside world in realtime using the [metadata](/runs/metadata) system. This is particularly useful for streaming LLM outputs or any other real-time data.
-## How it works
+
+ For frontend applications using React, see our [React hooks streams
+ documentation](/realtime/react-hooks/streams) for consuming streams in your UI.
+
+
+## How streams work
-The Streams API is a simple API that allows you to send data from your tasks to the outside world in realtime using the [metadata](/runs/metadata) system. You can send any kind of data that is streamed in realtime, but the most common use case is to send streaming output from streaming LLM providers, like OpenAI.
+Streams use the metadata system to send data chunks in real-time. You register a stream with a specific key using `metadata.stream`, and then consumers can subscribe to receive those chunks as they're emitted.
-## Usage
+## Basic streaming example
-To use the Streams API, you need to register a stream with a specific key using `metadata.stream`. The following example uses the OpenAI SDK with `stream: true` to stream the output of the LLM model in realtime:
+Here's how to stream data from OpenAI in your task:
```ts
import { task, metadata } from "@trigger.dev/sdk/v3";
@@ -56,12 +61,9 @@ export const myTask = task({
});
```
-You can then subscribe to the stream using the `runs.subscribeToRun` method:
+## Subscribing to streams from backend
-
- `runs.subscribeToRun` should be used from your backend or another task. To subscribe to a run from
- your frontend, you can use our [React hooks](/frontend/react-hooks).
-
+You can subscribe to the stream using the `runs.subscribeToRun` method with `.withStreams()`:
```ts
import { runs } from "@trigger.dev/sdk/v3";
@@ -86,7 +88,9 @@ async function subscribeToStream(runId: string) {
}
```
-You can register and subscribe to multiple streams in the same task. Let's add a stream from the response body of a fetch request:
+## Multiple streams
+
+You can register and subscribe to multiple streams in the same task:
```ts
import { task, metadata } from "@trigger.dev/sdk/v3";
@@ -97,7 +101,7 @@ const openai = new OpenAI({
});
export type STREAMS = {
- openai: OpenAI.ChatCompletionChunk; // The type of the chunk is determined by the provider
+ openai: OpenAI.ChatCompletionChunk;
fetch: string; // The response body will be an array of strings
};
@@ -110,7 +114,7 @@ export const myTask = task({
stream: true,
});
- // Register the stream with the key "openai"
+ // Register the OpenAI stream
await metadata.stream("openai", completion);
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
@@ -119,7 +123,7 @@ export const myTask = task({
return;
}
- // Register the stream with the key "fetch"
+ // Register a fetch response stream
// Pipe the response.body through a TextDecoderStream to convert it to a string
await metadata.stream("fetch", response.body.pipeThrough(new TextDecoderStream()));
},
@@ -133,7 +137,7 @@ export const myTask = task({
task.
-And then subscribing to the streams:
+Then subscribe to both streams:
```ts
import { runs } from "@trigger.dev/sdk/v3";
@@ -141,7 +145,6 @@ import type { myTask, STREAMS } from "./trigger/my-task";
// Somewhere in your backend
async function subscribeToStream(runId: string) {
- // Use a for-await loop to subscribe to the stream
for await (const part of runs.subscribeToRun(runId).withStreams()) {
switch (part.type) {
case "run": {
@@ -163,45 +166,9 @@ async function subscribeToStream(runId: string) {
}
```
-## React hooks
-
-If you're building a frontend application, you can use our React hooks to subscribe to streams. Here's an example of how you can use the `useRealtimeRunWithStreams` hook to subscribe to a stream:
-
-```tsx
-import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
-import type { myTask, STREAMS } from "./trigger/my-task";
-
-// Somewhere in your React component
-function MyComponent({ runId, publicAccessToken }: { runId: string; publicAccessToken: string }) {
- const { run, streams } = useRealtimeRunWithStreams(runId, {
- accessToken: publicAccessToken,
- });
-
- if (!run) {
- return
- );
-}
-```
-
-Read more about using the React hooks in the [React hooks](/frontend/react-hooks) documentation.
+## Using with the AI SDK
-## Usage with the `ai` SDK
-
-The [ai SDK](https://sdk.vercel.ai/docs/introduction) provides a higher-level API for working with AI models. You can use the `ai` SDK with the Streams API by using the `streamText` method:
+The [AI SDK](https://sdk.vercel.ai/docs/introduction) provides a higher-level API for working with AI models. You can use it with the Streams API:
```ts
import { openai } from "@ai-sdk/openai";
@@ -244,35 +211,9 @@ export const aiStreaming = schemaTask({
});
```
-And then render the stream in your frontend:
-
-```tsx
-import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
-import type { aiStreaming, STREAMS } from "./trigger/ai-streaming";
-
-function MyComponent({ runId, publicAccessToken }: { runId: string; publicAccessToken: string }) {
- const { streams } = useRealtimeRunWithStreams(runId, {
- accessToken: publicAccessToken,
- });
-
- if (!streams.openai) {
- return
Loading...
;
- }
-
- const text = streams.openai.join(""); // `streams.openai` is an array of strings
-
- return (
-
-
OpenAI response:
-
{text}
-
- );
-}
-```
-
-### Using tools and `fullStream`
+## Using AI SDK with tools
-When calling `streamText`, you can provide a `tools` object that allows the LLM to use additional tools. You can then access the tool call and results using the `fullStream` method:
+When using tools with the AI SDK, you can access tool calls and results using the `fullStream`:
```ts
import { openai } from "@ai-sdk/openai";
@@ -306,7 +247,7 @@ export const aiStreamingWithTools = schemaTask({
prompt: z
.string()
.default(
- "Based on the temperature, will I need to wear extra clothes today in San Fransico? Please be detailed."
+ "Based on the temperature, will I need to wear extra clothes today in San Francisco? Please be detailed."
),
}),
run: async ({ model, prompt }) => {
@@ -338,50 +279,9 @@ export const aiStreamingWithTools = schemaTask({
});
```
-Now you can get access to the tool call and results in your frontend:
-
-```tsx
-import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
-import type { aiStreamingWithTools, STREAMS } from "./trigger/ai-streaming";
-
-function MyComponent({ runId, publicAccessToken }: { runId: string; publicAccessToken: string }) {
- const { streams } = useRealtimeRunWithStreams(runId, {
- accessToken: publicAccessToken,
- });
-
- if (!streams.openai) {
- return
- {weatherLocation
- ? `The weather in ${weatherLocation} is ${weather} degrees.`
- : "No weather data"}
-
-
- );
-}
-```
-
-### Using `toolTask`
+## Using toolTask
-As you can see above, we defined a tool which will be used in the `aiStreamingWithTools` task. You can also define a Trigger.dev task that can be used as a tool, and will automatically be invoked with `triggerAndWait` when the tool is called. This is done using the `toolTask` function:
+You can define a Trigger.dev task that can be used as a tool, and will automatically be invoked with `triggerAndWait` when the tool is called:
```ts
import { openai } from "@ai-sdk/openai";
@@ -418,7 +318,7 @@ export const aiStreamingWithTools = schemaTask({
prompt: z
.string()
.default(
- "Based on the temperature, will I need to wear extra clothes today in San Fransico? Please be detailed."
+ "Based on the temperature, will I need to wear extra clothes today in San Francisco? Please be detailed."
),
}),
run: async ({ model, prompt }) => {
@@ -452,4 +352,4 @@ export const aiStreamingWithTools = schemaTask({
});
```
-
+{" "}
diff --git a/docs/realtime/backend/subscribe.mdx b/docs/realtime/backend/subscribe.mdx
new file mode 100644
index 0000000000..5f9ae34440
--- /dev/null
+++ b/docs/realtime/backend/subscribe.mdx
@@ -0,0 +1,116 @@
+---
+title: Subscribe functions
+sidebarTitle: Subscribe
+description: Subscribe to run updates using async iterators
+---
+
+These functions allow you to subscribe to run updates from your backend code. Each function returns an async iterator that yields run objects as they change.
+
+## runs.subscribeToRun
+
+Subscribes to all changes to a specific run.
+
+
+
+```ts Example
+import { runs } from "@trigger.dev/sdk/v3";
+
+for await (const run of runs.subscribeToRun("run_1234")) {
+ console.log(run);
+}
+```
+
+
+
+This function subscribes to all changes to a run. It returns an async iterator that yields the run object whenever the run is updated. The iterator will complete when the run is finished.
+
+**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific run. See our [authentication guide](/realtime/auth) for details.
+
+**Response**: The AsyncIterator yields the [run object](/realtime/run-object).
+
+## runs.subscribeToRunsWithTag
+
+Subscribes to all changes to runs with a specific tag.
+
+
+
+```ts Example
+import { runs } from "@trigger.dev/sdk/v3";
+
+for await (const run of runs.subscribeToRunsWithTag("user:1234")) {
+ console.log(run);
+}
+```
+
+
+
+This function subscribes to all changes to runs with a specific tag. It returns an async iterator that yields the run object whenever a run with the specified tag is updated. This iterator will never complete, so you must manually break out of the loop when you no longer want to receive updates.
+
+**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific tag. See our [authentication guide](/realtime/auth) for details.
+
+**Response**: The AsyncIterator yields the [run object](/realtime/run-object).
+
+## runs.subscribeToBatch
+
+Subscribes to all changes for runs in a batch.
+
+
+
+```ts Example
+import { runs } from "@trigger.dev/sdk/v3";
+
+for await (const run of runs.subscribeToBatch("batch_1234")) {
+ console.log(run);
+}
+```
+
+
+
+This function subscribes to all changes for runs in a batch. It returns an async iterator that yields a run object whenever a run in the batch is updated. The iterator does not complete on its own, you must manually `break` the loop when you want to stop listening for updates.
+
+**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific batch. See our [authentication guide](/realtime/auth) for details.
+
+**Response**: The AsyncIterator yields the [run object](/realtime/run-object).
+
+## Type safety
+
+You can infer the types of the run's payload and output by passing the type of the task to the subscribe functions:
+
+```ts
+import { runs, tasks } from "@trigger.dev/sdk/v3";
+import type { myTask } from "./trigger/my-task";
+
+async function myBackend() {
+ const handle = await tasks.trigger("my-task", { some: "data" });
+
+ for await (const run of runs.subscribeToRun(handle.id)) {
+ // run.payload and run.output are now typed
+ console.log(run.payload.some);
+
+ if (run.output) {
+ console.log(run.output.some);
+ }
+ }
+}
+```
+
+When using `subscribeToRunsWithTag`, you can pass a union of task types:
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { myTask, myOtherTask } from "./trigger/my-task";
+
+for await (const run of runs.subscribeToRunsWithTag("my-tag")) {
+ // Narrow down the type based on the taskIdentifier
+ switch (run.taskIdentifier) {
+ case "my-task": {
+ console.log("Run output:", run.output.foo); // Type-safe
+ break;
+ }
+ case "my-other-task": {
+ console.log("Run output:", run.output.bar); // Type-safe
+ break;
+ }
+ }
+}
+```
diff --git a/docs/realtime/how-it-works.mdx b/docs/realtime/how-it-works.mdx
new file mode 100644
index 0000000000..ed839eee25
--- /dev/null
+++ b/docs/realtime/how-it-works.mdx
@@ -0,0 +1,91 @@
+---
+title: How it works
+sidebarTitle: How it works
+description: Technical details about the Trigger.dev Realtime API
+---
+
+## Architecture
+
+The Realtime API is built on top of [Electric SQL](https://electric-sql.com/), an open-source PostgreSQL syncing engine. The Trigger.dev API wraps Electric SQL and provides a simple API to subscribe to [runs](/runs) and get real-time updates.
+
+## Run changes
+
+You will receive updates whenever a run changes for the following reasons:
+
+- The run moves to a new state. See our [run lifecycle docs](/runs#the-run-lifecycle) for more information.
+- [Run tags](/tags) are added or removed.
+- [Run metadata](/runs/metadata) is updated.
+
+## Run object
+
+The run object returned by realtime subscriptions is optimized for streaming updates and differs from the management API's run object. See the [run object reference](/realtime/run-object) for the complete schema and field descriptions.
+
+## Type-safety
+
+You can infer the types of the run's payload and output by passing the type of the task to the `subscribeToRun` function. This will give you type-safe access to the run's payload and output.
+
+```ts
+import { runs, tasks } from "@trigger.dev/sdk/v3";
+import type { myTask } from "./trigger/my-task";
+
+// Somewhere in your backend code
+async function myBackend() {
+ const handle = await tasks.trigger("my-task", { some: "data" });
+
+ for await (const run of runs.subscribeToRun(handle.id)) {
+ // This will log the run every time it changes
+ console.log(run.payload.some);
+
+ if (run.output) {
+ // This will log the output if it exists
+ console.log(run.output.some);
+ }
+ }
+}
+```
+
+When using `subscribeToRunsWithTag`, you can pass a union of task types for all the possible tasks that can have the tag.
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { myTask, myOtherTask } from "./trigger/my-task";
+
+// Somewhere in your backend code
+for await (const run of runs.subscribeToRunsWithTag("my-tag")) {
+ // You can narrow down the type based on the taskIdentifier
+ switch (run.taskIdentifier) {
+ case "my-task": {
+ console.log("Run output:", run.output.foo); // This will be type-safe
+ break;
+ }
+ case "my-other-task": {
+ console.log("Run output:", run.output.bar); // This will be type-safe
+ break;
+ }
+ }
+}
+```
+
+## Run metadata
+
+The run metadata API gives you the ability to add or update custom metadata on a run, which will cause the run to be updated. This allows you to extend the realtime API with custom data attached to a run that can be used for various purposes. Some common use cases include:
+
+- Adding a link to a related resource
+- Adding a reference to a user or organization
+- Adding a custom status with progress information
+
+See our [run metadata docs](/runs/metadata) for more on how to use this feature.
+
+### Using w/Realtime & React hooks
+
+We suggest combining run metadata with the realtime API and our [React hooks](/realtime/react-hooks) to bridge the gap between your trigger.dev tasks and your UI. This allows you to update your UI in real-time based on changes to the run metadata. As a simple example, you could add a custom status to a run with a progress value, and update your UI based on that progress.
+
+We have a full demo app repo available [here](https://github.com/triggerdotdev/nextjs-realtime-simple-demo)
+
+## Limits
+
+The Realtime API in the Trigger.dev Cloud limits the number of concurrent subscriptions, depending on your plan. If you exceed the limit, you will receive an error when trying to subscribe to a run. For more information, see our [pricing page](https://trigger.dev/pricing).
+
+## Known issues
+
+There is currently a known issue where the realtime API does not work if subscribing to a run that has a large payload or large output and are stored in object store instead of the database. We are working on a fix for this issue: https://github.com/triggerdotdev/trigger.dev/issues/1451. As a workaround you'll need to keep payloads and outputs below 128KB when using the realtime API.
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 718181dc16..6c9cbb34f9 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -1,272 +1,70 @@
---
title: Realtime overview
sidebarTitle: Overview
-description: Using the Trigger.dev v3 realtime API
+description: Using the Trigger.dev Realtime API to subscribe to runs in real-time.
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-Trigger.dev Realtime is a set of APIs that allow you to subscribe to runs and get real-time updates on the run status. This is useful for monitoring runs, updating UIs, and building realtime dashboards.
+Trigger.dev Realtime allows you subscribe to runs and get real-time updates as they execute. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
-## How it works
+## What you can subscribe to
-The Realtime API is built on top of [Electric SQL](https://electric-sql.com/), an open-source PostgreSQL syncing engine. The Trigger.dev API wraps Electric SQL and provides a simple API to subscribe to [runs](/runs) and get real-time updates.
+You can subscribe to real-time updates for:
-## Walkthrough
+- **Specific runs** - Monitor individual run progress
+- **Runs with specific tags** - Track runs by category or user
+- **Task runs** - All runs for specific tasks
+- **Batch runs** - All runs in a batch
-
-
-## Usage
-
-After you trigger a task, you can subscribe to the run using the `runs.subscribeToRun` function. This function returns an async iterator that you can use to get updates on the run status.
-
-```ts
-import { runs, tasks } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-async function myBackend() {
- const handle = await tasks.trigger("my-task", { some: "data" });
-
- for await (const run of runs.subscribeToRun(handle.id)) {
- // This will log the run every time it changes
- console.log(run);
- }
-}
-```
-
-Every time the run changes, the async iterator will yield the updated run. You can use this to update your UI, log the run status, or take any other action.
-
-Alternatively, you can subscribe to changes to any run that includes a specific tag (or tags) using the `runs.subscribeToRunsWithTag` function.
-
-```ts
-import { runs } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-for await (const run of runs.subscribeToRunsWithTag("user:1234")) {
- // This will log the run every time it changes, for all runs with the tag "user:1234"
- console.log(run);
-}
-```
-
-If you've used `batchTrigger` to trigger multiple runs, you can also subscribe to changes to all the runs triggered in the batch using the `runs.subscribeToBatch` function.
-
-```ts
-import { runs } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-for await (const run of runs.subscribeToBatch("batch-id")) {
- // This will log the run every time it changes, for all runs in the batch with the ID "batch-id"
- console.log(run);
-}
-```
-
-### React hooks
-
-We also provide a set of React hooks that make it easy to use the Realtime API in your React components. See the [React hooks doc](/frontend/react-hooks) for more information.
-
-## Run changes
-
-You will receive updates whenever a run changes for the following reasons:
-
-- The run moves to a new state. See our [run lifecycle docs](/runs#the-run-lifecycle) for more information.
-- [Run tags](/tags) are added or removed.
-- [Run metadata](/runs/metadata) is updated.
-
-## Run object
-
-The run object returned by the async iterator is NOT the same as the run object returned by the `runs.retrieve` function. This is because Electric SQL streams changes from a single PostgreSQL table, and the run object returned by `runs.retrieve` is a combination of multiple tables.
-
-The run object returned by the async iterator has the following fields:
-
-
- The run ID.
-
-
-
- The task identifier.
-
-
-
- The input payload for the run.
-
-
-
- The output result of the run.
-
-
-
- Timestamp when the run was created.
-
+You automatically receive the complete [run object](/realtime/run-object) containing status, timestamps, metadata, tags, and more whenever:
-
- Timestamp when the run was last updated.
-
+- Run status changes (queued β executing β completed, etc.)
+- [Run metadata](/runs/metadata) is updated
+- [Run tags](/tags) are added or removed
+- [Stream data](/realtime/backend#streams) is emitted
-
- Sequential number assigned to the run.
-
+Your tasks can also send additional custom data:
-
- Current status of the run.
+- **Metadata updates** - Update custom metadata on runs that gets streamed to subscribers ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/metadata))
+- **Stream function** - Stream data chunks in real-time, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
-
+## Authentication
-| Status | Description |
-| -------------------- | --------------------------------------------------------------------------------------------------------- |
-| `WAITING_FOR_DEPLOY` | Task hasn't been deployed yet but is waiting to be executed |
-| `QUEUED` | Run is waiting to be executed by a worker |
-| `EXECUTING` | Run is currently being executed by a worker |
-| `REATTEMPTING` | Run has failed and is waiting to be retried |
-| `FROZEN` | Run has been paused by the system, and will be resumed by the system |
-| `COMPLETED` | Run has been completed successfully |
-| `CANCELED` | Run has been canceled by the user |
-| `FAILED` | Run has been completed with errors |
-| `CRASHED` | Run has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage |
-| `INTERRUPTED` | Run was interrupted during execution, mostly this happens in development environments |
-| `SYSTEM_FAILURE` | Run has failed to complete, due to an error in the system |
-| `DELAYED` | Run has been scheduled to run at a specific time |
-| `EXPIRED` | Run has expired and won't be executed |
-| `TIMED_OUT` | Run has reached it's maxDuration and has been stopped |
+All Realtime subscriptions require authentication. See our [authentication guide](/realtime/auth) for details on:
-
-
+- Creating Public Access Tokens for frontend use
+- Scoping tokens to specific runs, tasks, tags, or batches
+- Auto-generated tokens from `tasks.trigger()`
-
- Duration of the run in milliseconds.
-
+## Implementation approaches
-
- Total cost of the run in cents.
-
+### Backend subscriptions
-
- Base cost of the run in cents before any additional charges.
-
+Use our server-side SDK to subscribe to runs from your backend code, other tasks, or serverless functions. Perfect for triggering workflows, sending notifications, or updating databases based on run status changes.
-
- Array of tags associated with the run.
-
+β **[See Backend functions guide](/realtime/backend)**
-
- Key used to ensure idempotent execution.
-
+### Frontend subscriptions
-
- Timestamp when the run expired.
-
+Use our React hooks to build real-time UIs that update as runs execute. Ideal for progress bars, status indicators, and live dashboards.
-
- Time-to-live duration for the run.
-
+β **[See React hooks guide](/realtime/react-hooks)**
-
- Timestamp when the run finished.
-
+## Technical details
-
- Timestamp when the run started.
-
+Learn more about the underlying technology and run object structure in our [How it Works](/realtime/how-it-works) guide.
-
- Timestamp until which the run is delayed.
-
+## Realtime demo
-
- Timestamp when the run was queued.
-
-
-
- Additional metadata associated with the run.
-
-
-
- Error information if the run failed.
-
-
-
- Indicates whether this is a test run.
-
-
-## Type-safety
-
-You can infer the types of the run's payload and output by passing the type of the task to the `subscribeToRun` function. This will give you type-safe access to the run's payload and output.
-
-```ts
-import { runs, tasks } from "@trigger.dev/sdk/v3";
-import type { myTask } from "./trigger/my-task";
-
-// Somewhere in your backend code
-async function myBackend() {
- const handle = await tasks.trigger("my-task", { some: "data" });
-
- for await (const run of runs.subscribeToRun(handle.id)) {
- // This will log the run every time it changes
- console.log(run.payload.some);
-
- if (run.output) {
- // This will log the output if it exists
- console.log(run.output.some);
- }
- }
-}
-```
-
-When using `subscribeToRunsWithTag`, you can pass a union of task types for all the possible tasks that can have the tag.
-
-```ts
-import { runs } from "@trigger.dev/sdk/v3";
-import type { myTask, myOtherTask } from "./trigger/my-task";
-
-// Somewhere in your backend code
-for await (const run of runs.subscribeToRunsWithTag("my-tag")) {
- // You can narrow down the type based on the taskIdentifier
- switch (run.taskIdentifier) {
- case "my-task": {
- console.log("Run output:", run.output.foo); // This will be type-safe
- break;
- }
- case "my-other-task": {
- console.log("Run output:", run.output.bar); // This will be type-safe
- break;
- }
- }
-}
-```
-
-## Run metadata
-
-The run metadata API gives you the ability to add or update custom metadata on a run, which will cause the run to be updated. This allows you to extend the realtime API with custom data attached to a run that can be used for various purposes. Some common use cases include:
-
-- Adding a link to a related resource
-- Adding a reference to a user or organization
-- Adding a custom status with progress information
-
-See our [run metadata docs](/runs/metadata) for more on how to use this feature.
-
-### Using w/Realtime & React hooks
-
-We suggest combining run metadata with the realtime API and our [React hooks](/frontend/react-hooks) to bridge the gap between your trigger.dev tasks and your UI. This allows you to update your UI in real-time based on changes to the run metadata. As a simple example, you could add a custom status to a run with a progress value, and update your UI based on that progress.
-
-We have a full demo app repo available [here](https://github.com/triggerdotdev/nextjs-realtime-simple-demo)
-
-## Realtime streams
-
-See our dedicated [Realtime streams](/realtime/streams) documentation for more information on how to use the Realtime streams API.
-
-## Limits
-
-The Realtime API in the Trigger.dev Cloud limits the number of concurrent subscriptions, depending on your plan. If you exceed the limit, you will receive an error when trying to subscribe to a run. For more information, see our [pricing page](https://trigger.dev/pricing).
-
-## Known issues
-
-There is currently a known issue where the realtime API does not work if subscribing to a run that has a large payload or large output and are stored in object store instead of the database. We are working on a fix for this issue: https://github.com/triggerdotdev/trigger.dev/issues/1451. As a workaround you'll need to keep payloads and outputs below 128KB when using the realtime API.
+
diff --git a/docs/realtime/react-hooks.mdx b/docs/realtime/react-hooks.mdx
deleted file mode 100644
index 8622bb7880..0000000000
--- a/docs/realtime/react-hooks.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: Realtime React hooks
-sidebarTitle: React hooks
-description: Subscribes to all changes to a run in a React component.
----
-
-See our [React hooks](/frontend/react-hooks) for more information about how to use the Realtime API from your frontend application.
diff --git a/docs/realtime/react-hooks/metadata.mdx b/docs/realtime/react-hooks/metadata.mdx
new file mode 100644
index 0000000000..990d4794fe
--- /dev/null
+++ b/docs/realtime/react-hooks/metadata.mdx
@@ -0,0 +1,357 @@
+---
+title: Metadata hooks
+sidebarTitle: Metadata
+description: Subscribe to run metadata updates in React components
+---
+
+import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
+
+These hooks allow you to subscribe to run metadata updates in your React components. Metadata is perfect for displaying progress bars, status indicators, and other real-time information from your tasks.
+
+
+ To learn how to update metadata from your tasks, see our [backend metadata
+ documentation](/realtime/backend/metadata).
+
+
+## useRealtimeRun with metadata
+
+The `useRealtimeRun` hook automatically includes metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
+
+```tsx
+"use client"; // This is needed for Next.js App Router or other RSC frameworks
+
+import { useRealtimeRun } from "@trigger.dev/react-hooks";
+
+export function ProgressMonitor({
+ runId,
+ publicAccessToken,
+}: {
+ runId: string;
+ publicAccessToken: string;
+}) {
+ const { run, error, isLoading } = useRealtimeRun(runId, {
+ accessToken: publicAccessToken,
+ });
+
+ if (isLoading) return
+ );
+}
+```
+
+## Authentication
+
+React hooks require public access tokens for authentication. These tokens can be scoped to specific runs, tasks, tags, or batches. See our [authentication guide](/realtime/auth) for details on creating and using public access tokens.
+
+{" "}
diff --git a/docs/frontend/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
similarity index 88%
rename from docs/frontend/react-hooks/overview.mdx
rename to docs/realtime/react-hooks/overview.mdx
index 3dedfcaa2b..c1b53b7641 100644
--- a/docs/frontend/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -1,12 +1,12 @@
---
-title: Overview
+title: React hooks overview
sidebarTitle: Overview
-description: Using the Trigger.dev v3 API from your React application.
+description: Using the Trigger.dev Realtime API from your React applications.
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-Our react hooks package provides a set of hooks that make it easy to interact with the Trigger.dev API from your React application, using our [frontend API](/frontend/overview). You can use these hooks to fetch runs, and subscribe to real-time updates, and trigger tasks from your frontend application.
+Our React hooks package provides a set of hooks that make it easy to interact with the Trigger.dev Realtime API from your React applications. You can use these hooks to subscribe to real-time updates, and trigger tasks from your frontend.
## Installation
@@ -30,7 +30,7 @@ yarn install @trigger.dev/react-hooks
## Authentication
-All hooks accept an optional last argument `options` that accepts an `accessToken` param, which should be a valid Public Access Token. Learn more about [generating tokens in the frontend guide](/frontend/overview).
+All hooks accept an optional last argument `options` that accepts an `accessToken` param, which should be a valid Public Access Token. Learn more about [generating tokens in our authentication guide](/realtime/auth).
```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";
@@ -51,7 +51,9 @@ export function MyComponent({
}
```
-Alternatively, you can use our `TriggerAuthContext` provider
+### TriggerAuthContext
+
+Alternatively, you can use our `TriggerAuthContext` provider to avoid passing the token to every hook:
```tsx
import { TriggerAuthContext } from "@trigger.dev/react-hooks";
@@ -250,6 +252,15 @@ We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](ht
we recommend using the Realtime hooks for most use-cases.
+## Available hooks
+
+We provide several categories of hooks:
+
+- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, and streams using real-time updates
+- **[Metadata hooks](/realtime/react-hooks/metadata)** - Subscribe to run metadata updates in React components
+- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
+- **[SWR hooks](#swr-hooks)** - Fetch data once and cache it using SWR
+
## SWR Hooks
### useRun
@@ -291,7 +302,7 @@ export function MyComponent({ runId }: { runId: string }) {
}
```
-### Common options
+### Common SWR options
You can pass the following options to the all SWR hooks:
@@ -308,7 +319,7 @@ You can pass the following options to the all SWR hooks:
use-cases. Use the Realtime hooks instead.
-### Common return values
+### Common SWR return values
An error object if an error occurred while fetching the data.
@@ -326,12 +337,4 @@ You can pass the following options to the all SWR hooks:
A boolean indicating if an error occurred while fetching the data.
-## Realtime hooks
-
-See our [Realtime hooks documentation](/frontend/react-hooks/realtime) for more information.
-
-## Trigger Hooks
-
-See our [Trigger hooks documentation](/frontend/react-hooks/triggering) for more information.
-
-
+{" "}
diff --git a/docs/frontend/react-hooks/realtime.mdx b/docs/realtime/react-hooks/realtime.mdx
similarity index 65%
rename from docs/frontend/react-hooks/realtime.mdx
rename to docs/realtime/react-hooks/realtime.mdx
index d1cb260faa..25e4a204a7 100644
--- a/docs/frontend/react-hooks/realtime.mdx
+++ b/docs/realtime/react-hooks/realtime.mdx
@@ -9,7 +9,7 @@ import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
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.
+- Read how to [setup and authenticate](/realtime/react-hooks) using the `@trigger.dev/react-hooks` package.
## Hooks
@@ -89,7 +89,7 @@ export function MyComponent({
}
```
-See our [Realtime documentation](/realtime) for more information about the type of the run object and more.
+See our [run object reference](/realtime/run-object) for the complete schema and [How it Works documentation](/realtime/how-it-works) for more technical details.
### useRealtimeRunsWithTag
@@ -194,110 +194,6 @@ export function MyComponent({ batchId }: { batchId: string }) {
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
Error: {error.message}
;
-
- return (
-
-
Run: {run.id}
-
- {Object.keys(streams).map((stream) => (
-
Stream: {stream}
- ))}
-
-
- );
-}
-```
-
-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(runId, {
- accessToken: publicAccessToken,
- });
-
- if (error) return
- );
-}
-```
-
-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(runId, {
- accessToken: publicAccessToken,
- });
-
- if (error) return
- );
-}
-```
-
## Common options
### accessToken & baseURL
@@ -386,35 +282,4 @@ export function MyComponent({
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
Error: {error.message}
;
-
- return (
-
- {runs.map((run) => (
-
Run: {run.id}
- ))}
-
- );
-}
-```
-
-
+{" "}
diff --git a/docs/realtime/react-hooks/streams.mdx b/docs/realtime/react-hooks/streams.mdx
new file mode 100644
index 0000000000..b2c79de79e
--- /dev/null
+++ b/docs/realtime/react-hooks/streams.mdx
@@ -0,0 +1,225 @@
+---
+title: Streams hooks
+sidebarTitle: Streams
+description: Subscribe to real-time streams from your tasks in React components
+---
+
+import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
+
+These hooks allow you to consume real-time streams from your tasks. Streams are useful for displaying AI/LLM outputs as they're generated, or any other real-time data from your tasks.
+
+
+ To learn how to emit streams from your tasks, see our [backend streams
+ documentation](/realtime/backend#streams).
+
+
+## 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.
+
+```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
Error: {error.message}
;
+
+ return (
+
+
Run: {run.id}
+
+ {Object.keys(streams).map((stream) => (
+
Stream: {stream}
+ ))}
+
+
+ );
+}
+```
+
+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(runId, {
+ accessToken: publicAccessToken,
+ });
+
+ if (error) return
+ );
+}
+```
+
+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(runId, {
+ accessToken: publicAccessToken,
+ });
+
+ if (error) return
+ {weatherLocation
+ ? `The weather in ${weatherLocation} is ${weather} degrees.`
+ : "No weather data"}
+
+
+ );
+}
+```
+
+## Common options
+
+### 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 { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
+
+export function MyComponent({
+ runId,
+ publicAccessToken,
+}: {
+ runId: string;
+ publicAccessToken: string;
+}) {
+ const { run, streams, error } = useRealtimeRunWithStreams(runId, {
+ accessToken: publicAccessToken,
+ experimental_throttleInMs: 1000, // Throttle updates to once per second
+ });
+
+ if (error) return
Error: {error.message}
;
+
+ return (
+
+
Run: {run.id}
+ {/* Display streams */}
+
+ );
+}
+```
+
+All other options (accessToken, baseURL, enabled, id) work the same as the other realtime hooks. See our [realtime hooks documentation](/realtime/react-hooks/realtime#common-options) for more details.
+
+{" "}
diff --git a/docs/frontend/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
similarity index 92%
rename from docs/frontend/react-hooks/triggering.mdx
rename to docs/realtime/react-hooks/triggering.mdx
index 26bfcb1c12..d6dd3a2da3 100644
--- a/docs/frontend/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -12,29 +12,9 @@ We provide a set of hooks that can be used to trigger tasks from your frontend a
We've created a [Demo application](https://github.com/triggerdotdev/realtime-llm-battle) that demonstrates how to use our React hooks to trigger tasks in a Next.js application. The application uses the `@trigger.dev/react-hooks` package to trigger a task and subscribe to the run in real-time.
-## Installation
-
-Install the `@trigger.dev/react-hooks` package in your project:
-
-
-
-```bash npm
-npm add @trigger.dev/react-hooks
-```
-
-```bash pnpm
-pnpm add @trigger.dev/react-hooks
-```
-
-```bash yarn
-yarn install @trigger.dev/react-hooks
-```
-
-
-
## Authentication
-To authenticate a trigger hook, you must provide a special one-time use "trigger" token. These tokens are very similar to [Public Access Tokens](/frontend/overview#authentication), but they can only be used once to trigger a task. You can generate a trigger token using the `auth.createTriggerPublicToken` function in your backend code:
+To authenticate a trigger hook, you must provide a special one-time use "trigger" token. These tokens are very similar to [Public Access Tokens](/realtime/auth), but they can only be used once to trigger a task. You can generate a trigger token using the `auth.createTriggerPublicToken` function in your backend code:
```ts
import { auth } from "@trigger.dev/sdk/v3";
@@ -74,7 +54,7 @@ const triggerToken = await auth.createTriggerPublicToken("my-task", {
After generating the trigger token in your backend, you must pass it to your frontend application.
We have a guide on how to do this in the [React hooks
- overview](/frontend/react-hooks/overview#passing-the-token-to-the-frontend).
+ overview](/realtime/react-hooks#passing-the-token-to-the-frontend).
## Hooks
@@ -127,7 +107,7 @@ submit({ foo: "bar" }, { tags: ["tag1", "tag2"] });
#### Using the handle object
-You can use the `handle` object to initiate a subsequent [realtime hook](/frontend/react-hooks/realtime#userealtimerun) to subscribe to the run.
+You can use the `handle` object to initiate a subsequent [realtime hook](/realtime/react-hooks/realtime#userealtimerun) to subscribe to the run.
```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks
@@ -251,4 +231,4 @@ export function MyComponent({ publicAccessToken }: { publicAccessToken: string }
}
```
-
+{" "}
diff --git a/docs/realtime/run-object.mdx b/docs/realtime/run-object.mdx
new file mode 100644
index 0000000000..097bf93400
--- /dev/null
+++ b/docs/realtime/run-object.mdx
@@ -0,0 +1,142 @@
+---
+title: "The run object"
+sidebarTitle: "The run object"
+description: "The run object schema for Realtime subscriptions"
+---
+
+This is the run object returned by Realtime subscriptions (e.g., `runs.subscribeToRun()`).
+
+## Properties
+
+
+ The run ID.
+
+
+
+ The task identifier.
+
+
+
+ The input payload for the run.
+
+
+
+ The output result of the run.
+
+
+
+ Timestamp when the run was created.
+
+
+
+ Timestamp when the run was last updated.
+
+
+
+ Sequential number assigned to the run.
+
+
+
+ Current status of the run.
+
+
+
+| Status | Description |
+| -------------------- | --------------------------------------------------------------------------------------------------------- |
+| `WAITING_FOR_DEPLOY` | Task hasn't been deployed yet but is waiting to be executed |
+| `QUEUED` | Run is waiting to be executed by a worker |
+| `EXECUTING` | Run is currently being executed by a worker |
+| `REATTEMPTING` | Run has failed and is waiting to be retried |
+| `FROZEN` | Run has been paused by the system, and will be resumed by the system |
+| `COMPLETED` | Run has been completed successfully |
+| `CANCELED` | Run has been canceled by the user |
+| `FAILED` | Run has been completed with errors |
+| `CRASHED` | Run has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage |
+| `INTERRUPTED` | Run was interrupted during execution, mostly this happens in development environments |
+| `SYSTEM_FAILURE` | Run has failed to complete, due to an error in the system |
+| `DELAYED` | Run has been scheduled to run at a specific time |
+| `EXPIRED` | Run has expired and won't be executed |
+| `TIMED_OUT` | Run has reached it's maxDuration and has been stopped |
+
+
+
+
+
+ Duration of the run in milliseconds.
+
+
+
+ Total cost of the run in cents.
+
+
+
+ Base cost of the run in cents before any additional charges.
+
+
+
+ Array of tags associated with the run.
+
+
+
+ Key used to ensure idempotent execution.
+
+
+
+ Timestamp when the run expired.
+
+
+
+ Time-to-live duration for the run.
+
+
+
+ Timestamp when the run finished.
+
+
+
+ Timestamp when the run started.
+
+
+
+ Timestamp until which the run is delayed.
+
+
+
+ Timestamp when the run was queued.
+
+
+
+ Additional metadata associated with the run.
+
+
+
+ Error information if the run failed.
+
+
+
+ Indicates whether this is a test run.
+
+
+## Type safety
+
+You can get type safety for the run's payload and output by passing your task type to subscription functions:
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { myTask } from "./trigger/my-task";
+
+for await (const run of runs.subscribeToRun(runId)) {
+ // run.payload and run.output are now typed based on your task
+ console.log(run.payload.someProperty); // Type-safe
+
+ if (run.output) {
+ console.log(run.output.result); // Type-safe
+ }
+}
+```
+
+This works with all realtime subscription functions:
+
+- `runs.subscribeToRun()`
+- `runs.subscribeToRunsWithTag()`
+- `runs.subscribeToBatch()`
diff --git a/docs/realtime/subscribe-to-batch.mdx b/docs/realtime/subscribe-to-batch.mdx
deleted file mode 100644
index 9e0364b019..0000000000
--- a/docs/realtime/subscribe-to-batch.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: runs.subscribeToBatch
-sidebarTitle: subscribeToBatch
-description: Subscribes to all changes for runs in a batch.
----
-
-import RunObject from "/snippets/realtime/run-object.mdx";
-
-
-
-```ts Example
-import { runs } from "@trigger.dev/sdk/v3";
-
-for await (const run of runs.subscribeToBatch("batch_1234")) {
- console.log(run);
-}
-```
-
-
-
-This function subscribes to all changes for runs in a batch. It returns an async iterator that yields the a run object whenever a run in the batch is updated. The iterator does not complete on it's own, you must manually `break` the loop when you want to stop listening for updates.
-
-### Authentication
-
-This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with one of the following scopes:
-
-- `read:batch:`
-- `read:runs` will provide access to all runs (not recommended for production use)
-
-To generate a public access token, use the `auth.createPublicToken` function:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-const publicToken = await auth.createPublicToken({
- scopes: {
- read: {
- batch: ["batch_1234"],
- },
- },
-});
-```
-
-### Response
-
-The AsyncIterator yields an object with the following properties:
-
-
diff --git a/docs/realtime/subscribe-to-run.mdx b/docs/realtime/subscribe-to-run.mdx
deleted file mode 100644
index c2b4d88ea7..0000000000
--- a/docs/realtime/subscribe-to-run.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: runs.subscribeToRun
-sidebarTitle: subscribeToRun
-description: Subscribes to all changes to a run.
----
-
-import RunObject from "/snippets/realtime/run-object.mdx";
-
-
-
-```ts Example
-import { runs } from "@trigger.dev/sdk/v3";
-
-for await (const run of runs.subscribeToRun("run_1234")) {
- console.log(run);
-}
-```
-
-
-
-This function subscribes to all changes to a run. It returns an async iterator that yields the run object whenever the run is updated. The iterator will complete when the run is finished.
-
-### Authentication
-
-This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with one of the following scopes:
-
-- `read:runs`
-- `read:runs:`
-
-To generate a public access token, use the `auth.createPublicToken` function:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-const publicToken = await auth.createPublicToken({
- scopes: {
- read: {
- runs: ["run_1234"],
- },
- },
-});
-```
-
-### Response
-
-The AsyncIterator yields an object with the following properties:
-
-
diff --git a/docs/realtime/subscribe-to-runs-with-tag.mdx b/docs/realtime/subscribe-to-runs-with-tag.mdx
deleted file mode 100644
index 950a4eefaf..0000000000
--- a/docs/realtime/subscribe-to-runs-with-tag.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: runs.subscribeToRunsWithTag
-sidebarTitle: subscribeToRunsWithTag
-description: Subscribes to all changes to runs with a specific tag.
----
-
-import RunObject from "/snippets/realtime/run-object.mdx";
-
-
-
-```ts Example
-import { runs } from "@trigger.dev/sdk/v3";
-
-for await (const run of runs.subscribeToRunsWithTag("user:1234")) {
- console.log(run);
-}
-```
-
-
-
-This function subscribes to all changes to runs with a specific tag. It returns an async iterator that yields the run object whenever a run with the specified tag is updated. This iterator will never complete, so you must manually break out of the loop when you no longer want to receive updates.
-
-### Authentication
-
-This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with one of the following scopes:
-
-- `read:runs`
-- `read:tags:`
-
-To generate a public access token, use the `auth.createPublicToken` function:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-const publicToken = await auth.createPublicToken({
- scopes: {
- read: {
- tags: ["user:1234"],
- },
- },
-});
-```
-
-### Response
-
-The AsyncIterator yields an object with the following properties:
-
-
From 0c4e8aca92af97fff3b669ca71467c88086e2add Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:03:09 +0100
Subject: [PATCH 02/27] Updated the overview and nav
---
docs/docs.json | 4 +-
docs/realtime/react-hooks/overview.mdx | 207 ++-----------------------
2 files changed, 11 insertions(+), 200 deletions(-)
diff --git a/docs/docs.json b/docs/docs.json
index 12b1565064..ca60c022e1 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -122,10 +122,10 @@
"group": "React hooks (frontend)",
"pages": [
"realtime/react-hooks/overview",
+ "realtime/react-hooks/triggering",
"realtime/react-hooks/realtime",
"realtime/react-hooks/metadata",
- "realtime/react-hooks/streams",
- "realtime/react-hooks/triggering"
+ "realtime/react-hooks/streams"
]
},
{
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index c1b53b7641..1882f590ed 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -30,7 +30,7 @@ yarn install @trigger.dev/react-hooks
## Authentication
-All hooks accept an optional last argument `options` that accepts an `accessToken` param, which should be a valid Public Access Token. Learn more about [generating tokens in our authentication guide](/realtime/auth).
+All hooks require authentication with a Public Access Token. Pass the token via the `accessToken` option:
```tsx
import { useRealtimeRun } from "@trigger.dev/react-hooks";
@@ -43,7 +43,7 @@ export function MyComponent({
publicAccessToken: string;
}) {
const { run, error } = useRealtimeRun(runId, {
- accessToken: publicAccessToken, // This is required
+ accessToken: publicAccessToken,
baseURL: "https://your-trigger-dev-instance.com", // optional, only needed if you are self-hosting Trigger.dev
});
@@ -51,196 +51,16 @@ export function MyComponent({
}
```
-### TriggerAuthContext
+Learn more about [generating and managing tokens in our authentication guide](/realtime/auth).
-Alternatively, you can use our `TriggerAuthContext` provider to avoid passing the token to every hook:
-
-```tsx
-import { TriggerAuthContext } from "@trigger.dev/react-hooks";
-
-export function SetupTrigger({ publicAccessToken }: { publicAccessToken: string }) {
- return (
-
-
-
- );
-}
-```
-
-Now children components can use the hooks to interact with the Trigger.dev API. If you are self-hosting Trigger.dev, you can provide the `baseURL` to the `TriggerAuthContext` provider.
-
-```tsx
-import { TriggerAuthContext } from "@trigger.dev/react-hooks";
-
-export function SetupTrigger({ publicAccessToken }: { publicAccessToken: string }) {
- return (
-
-
-
- );
-}
-```
-
-### Next.js and client components
-
-If you are using Next.js with the App Router, you have to make sure the component that uses the `TriggerAuthContext` is a client component. So for example, the following code will not work:
-
-```tsx app/page.tsx
-import { TriggerAuthContext } from "@trigger.dev/react-hooks";
-
-export default function Page() {
- return (
-
-
-
- );
-}
-```
-
-That's because `Page` is a server component and the `TriggerAuthContext.Provider` uses client-only react code. To fix this, wrap the `TriggerAuthContext.Provider` in a client component:
-
-```ts components/TriggerProvider.tsx
-"use client";
-
-import { TriggerAuthContext } from "@trigger.dev/react-hooks";
-
-export function TriggerProvider({
- accessToken,
- children,
-}: {
- accessToken: string;
- children: React.ReactNode;
-}) {
- return (
-
- {children}
-
- );
-}
-```
-
-### Passing the token to the frontend
-
-Techniques for passing the token to the frontend vary depending on your setup. Here are a few ways to do it for different setups:
-
-#### Next.js App Router
-
-If you are using Next.js with the App Router and you are triggering a task from a server action, you can use cookies to store and pass the token to the frontend.
-
-```tsx actions/trigger.ts
-"use server";
-
-import { tasks } from "@trigger.dev/sdk/v3";
-import type { exampleTask } from "@/trigger/example";
-import { redirect } from "next/navigation";
-import { cookies } from "next/headers";
-
-export async function startRun() {
- const handle = await tasks.trigger("example", { foo: "bar" });
-
- // Set the auto-generated publicAccessToken in a cookie
- cookies().set("publicAccessToken", handle.publicAccessToken); // β this token only has access to read this run
-
- redirect(`/runs/${handle.id}`);
-}
-```
-
-Then in the `/runs/[id].tsx` page, you can read the token from the cookie and pass it to the `TriggerProvider`.
-
-```tsx pages/runs/[id].tsx
-import { TriggerProvider } from "@/components/TriggerProvider";
-
-export default function RunPage({ params }: { params: { id: string } }) {
- const publicAccessToken = cookies().get("publicAccessToken");
-
- return (
-
-
-
- );
-}
-```
-
-Instead of a cookie, you could also use a query parameter to pass the token to the frontend:
-
-```tsx actions/trigger.ts
-import { tasks } from "@trigger.dev/sdk/v3";
-import type { exampleTask } from "@/trigger/example";
-import { redirect } from "next/navigation";
-import { cookies } from "next/headers";
-
-export async function startRun() {
- const handle = await tasks.trigger("example", { foo: "bar" });
-
- redirect(`/runs/${handle.id}?publicAccessToken=${handle.publicAccessToken}`);
-}
-```
-
-And then in the `/runs/[id].tsx` page:
-
-```tsx pages/runs/[id].tsx
-import { TriggerProvider } from "@/components/TriggerProvider";
-
-export default function RunPage({
- params,
- searchParams,
-}: {
- params: { id: string };
- searchParams: { publicAccessToken: string };
-}) {
- return (
-
-
-
- );
-}
-```
-
-Another alternative would be to use a server-side rendered page to fetch the token and pass it to the frontend:
-
-
-
-```tsx pages/runs/[id].tsx
-import { TriggerProvider } from "@/components/TriggerProvider";
-import { generatePublicAccessToken } from "@/trigger/auth";
-
-export default async function RunPage({ params }: { params: { id: string } }) {
- // This will be executed on the server only
- const publicAccessToken = await generatePublicAccessToken(params.id);
-
- return (
-
-
-
- );
-}
-```
+## Available hooks
-```tsx trigger/auth.ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-export async function generatePublicAccessToken(runId: string) {
- return auth.createPublicToken({
- scopes: {
- read: {
- runs: [runId],
- },
- },
- expirationTime: "1h",
- });
-}
-```
+We provide several categories of hooks:
-
+- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
+- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, and streams using real-time updates
+- **[Metadata hooks](/realtime/react-hooks/metadata)** - Subscribe to run metadata updates in React components
+- **[SWR hooks](#swr-hooks)** - Fetch data once and cache it using SWR
## SWR vs Realtime hooks
@@ -252,15 +72,6 @@ We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](ht
we recommend using the Realtime hooks for most use-cases.
-## Available hooks
-
-We provide several categories of hooks:
-
-- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, and streams using real-time updates
-- **[Metadata hooks](/realtime/react-hooks/metadata)** - Subscribe to run metadata updates in React components
-- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
-- **[SWR hooks](#swr-hooks)** - Fetch data once and cache it using SWR
-
## SWR Hooks
### useRun
From f9cf1643f8609c92a6be5dcbe004df5628828498 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:07:22 +0100
Subject: [PATCH 03/27] Separated out SWR hooks
---
docs/docs.json | 3 +-
docs/realtime/react-hooks/overview.mdx | 78 +----------------------
docs/realtime/react-hooks/swr.mdx | 87 ++++++++++++++++++++++++++
3 files changed, 90 insertions(+), 78 deletions(-)
create mode 100644 docs/realtime/react-hooks/swr.mdx
diff --git a/docs/docs.json b/docs/docs.json
index ca60c022e1..ac21773d91 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -125,7 +125,8 @@
"realtime/react-hooks/triggering",
"realtime/react-hooks/realtime",
"realtime/react-hooks/metadata",
- "realtime/react-hooks/streams"
+ "realtime/react-hooks/streams",
+ "realtime/react-hooks/swr"
]
},
{
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index 1882f590ed..46a49bc049 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -60,7 +60,7 @@ We provide several categories of hooks:
- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, and streams using real-time updates
- **[Metadata hooks](/realtime/react-hooks/metadata)** - Subscribe to run metadata updates in React components
-- **[SWR hooks](#swr-hooks)** - Fetch data once and cache it using SWR
+- **[SWR hooks](/realtime/react-hooks/swr)** - Fetch data once and cache it using SWR
## SWR vs Realtime hooks
@@ -72,80 +72,4 @@ We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](ht
we recommend using the Realtime hooks for most use-cases.
-## SWR Hooks
-
-### useRun
-
-The `useRun` hook allows you to fetch a run by its ID.
-
-```tsx
-"use client"; // This is needed for Next.js App Router or other RSC frameworks
-
-import { useRun } from "@trigger.dev/react-hooks";
-
-export function MyComponent({ runId }: { runId: string }) {
- const { run, error, isLoading } = useRun(runId);
-
- if (isLoading) return
Loading...
;
- if (error) return
Error: {error.message}
;
-
- return
Run: {run.id}
;
-}
-```
-
-The `run` object returned is the same as the [run object](/management/runs/retrieve) returned by the Trigger.dev API. To correctly type the run's payload and output, you can provide the type of your task to the `useRun` hook:
-
-```tsx
-import { useRun } from "@trigger.dev/react-hooks";
-import type { myTask } from "@/trigger/myTask";
-
-export function MyComponent({ runId }: { runId: string }) {
- const { run, error, isLoading } = useRun(runId, {
- refreshInterval: 0, // Disable polling
- });
-
- if (isLoading) return
Loading...
;
- if (error) return
Error: {error.message}
;
-
- // Now run.payload and run.output are correctly typed
-
- return
Run: {run.id}
;
-}
-```
-
-### Common SWR options
-
-You can pass the following options to the all SWR hooks:
-
-
- Revalidate the data when the window regains focus.
-
-
-
- Revalidate the data when the browser regains a network connection.
-
-
-
- Poll for updates at the specified interval (in milliseconds). Polling is not recommended for most
- use-cases. Use the Realtime hooks instead.
-
-
-### Common SWR return values
-
-
- An error object if an error occurred while fetching the data.
-
-
-
- A boolean indicating if the data is currently being fetched.
-
-
-
- A boolean indicating if the data is currently being revalidated.
-
-
-
- A boolean indicating if an error occurred while fetching the data.
-
-
{" "}
diff --git a/docs/realtime/react-hooks/swr.mdx b/docs/realtime/react-hooks/swr.mdx
new file mode 100644
index 0000000000..6132d3b9c7
--- /dev/null
+++ b/docs/realtime/react-hooks/swr.mdx
@@ -0,0 +1,87 @@
+---
+title: SWR hooks
+sidebarTitle: SWR
+description: Fetch and cache data using SWR-based hooks
+---
+
+SWR hooks use the [swr](https://swr.vercel.app/) library to fetch data once and cache it. These hooks are useful when you need to fetch data without real-time updates.
+
+
+ While SWR can be configured to poll for updates, we recommend using the [Realtime
+ hooks](/realtime/react-hooks/realtime) for most use-cases due to rate-limits and the way the
+ Trigger.dev API works.
+
+
+## useRun
+
+The `useRun` hook allows you to fetch a run by its ID.
+
+```tsx
+"use client"; // This is needed for Next.js App Router or other RSC frameworks
+
+import { useRun } from "@trigger.dev/react-hooks";
+
+export function MyComponent({ runId }: { runId: string }) {
+ const { run, error, isLoading } = useRun(runId);
+
+ if (isLoading) return
Loading...
;
+ if (error) return
Error: {error.message}
;
+
+ return
Run: {run.id}
;
+}
+```
+
+The `run` object returned is the same as the [run object](/management/runs/retrieve) returned by the Trigger.dev API. To correctly type the run's payload and output, you can provide the type of your task to the `useRun` hook:
+
+```tsx
+import { useRun } from "@trigger.dev/react-hooks";
+import type { myTask } from "@/trigger/myTask";
+
+export function MyComponent({ runId }: { runId: string }) {
+ const { run, error, isLoading } = useRun(runId, {
+ refreshInterval: 0, // Disable polling
+ });
+
+ if (isLoading) return
Loading...
;
+ if (error) return
Error: {error.message}
;
+
+ // Now run.payload and run.output are correctly typed
+
+ return
Run: {run.id}
;
+}
+```
+
+## Common SWR options
+
+You can pass the following options to the all SWR hooks:
+
+
+ Revalidate the data when the window regains focus.
+
+
+
+ Revalidate the data when the browser regains a network connection.
+
+
+
+ Poll for updates at the specified interval (in milliseconds). Polling is not recommended for most
+ use-cases. Use the Realtime hooks instead.
+
+
+## Common SWR return values
+
+
+ An error object if an error occurred while fetching the data.
+
+
+
+ A boolean indicating if the data is currently being fetched.
+
+
+
+ A boolean indicating if the data is currently being revalidated.
+
+
+
+ A boolean indicating if an error occurred while fetching the data.
+{" "}
From f3dab2a5d952870b9f4a930e4202df1fb9eb6b32 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:30:26 +0100
Subject: [PATCH 04/27] Restructured metadata sections
---
docs/docs.json | 1 -
docs/realtime/backend/metadata.mdx | 3 +-
docs/realtime/overview.mdx | 2 +-
docs/realtime/react-hooks/metadata.mdx | 357 -----------------------
docs/realtime/react-hooks/overview.mdx | 6 +-
docs/realtime/react-hooks/realtime.mdx | 349 +++++++++++++++++++++-
docs/realtime/react-hooks/triggering.mdx | 45 ---
7 files changed, 352 insertions(+), 411 deletions(-)
delete mode 100644 docs/realtime/react-hooks/metadata.mdx
diff --git a/docs/docs.json b/docs/docs.json
index ac21773d91..ee8b3f700f 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -124,7 +124,6 @@
"realtime/react-hooks/overview",
"realtime/react-hooks/triggering",
"realtime/react-hooks/realtime",
- "realtime/react-hooks/metadata",
"realtime/react-hooks/streams",
"realtime/react-hooks/swr"
]
diff --git a/docs/realtime/backend/metadata.mdx b/docs/realtime/backend/metadata.mdx
index 7c35d6f4bf..71c75592cb 100644
--- a/docs/realtime/backend/metadata.mdx
+++ b/docs/realtime/backend/metadata.mdx
@@ -10,7 +10,8 @@ The metadata API allows you to update custom metadata on runs and receive real-t
For frontend applications using React, see our [React hooks metadata
- documentation](/realtime/react-hooks/metadata) for consuming metadata updates in your UI.
+ documentation](/realtime/react-hooks/realtime#using-metadata) for consuming metadata updates in
+ your UI.
## How metadata works with realtime
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 6c9cbb34f9..9a74bbee0c 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -26,7 +26,7 @@ You automatically receive the complete [run object](/realtime/run-object) contai
Your tasks can also send additional custom data:
-- **Metadata updates** - Update custom metadata on runs that gets streamed to subscribers ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/metadata))
+- **Metadata updates** - Update custom metadata on runs that gets streamed to subscribers ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/realtime#using-metadata))
- **Stream function** - Stream data chunks in real-time, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
## Authentication
diff --git a/docs/realtime/react-hooks/metadata.mdx b/docs/realtime/react-hooks/metadata.mdx
deleted file mode 100644
index 990d4794fe..0000000000
--- a/docs/realtime/react-hooks/metadata.mdx
+++ /dev/null
@@ -1,357 +0,0 @@
----
-title: Metadata hooks
-sidebarTitle: Metadata
-description: Subscribe to run metadata updates in React components
----
-
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
-These hooks allow you to subscribe to run metadata updates in your React components. Metadata is perfect for displaying progress bars, status indicators, and other real-time information from your tasks.
-
-
- To learn how to update metadata from your tasks, see our [backend metadata
- documentation](/realtime/backend/metadata).
-
-
-## useRealtimeRun with metadata
-
-The `useRealtimeRun` hook automatically includes metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
-
-```tsx
-"use client"; // This is needed for Next.js App Router or other RSC frameworks
-
-import { useRealtimeRun } from "@trigger.dev/react-hooks";
-
-export function ProgressMonitor({
- runId,
- publicAccessToken,
-}: {
- runId: string;
- publicAccessToken: string;
-}) {
- const { run, error, isLoading } = useRealtimeRun(runId, {
- accessToken: publicAccessToken,
- });
-
- if (isLoading) return
- );
-}
-```
-
-## Authentication
-
-React hooks require public access tokens for authentication. These tokens can be scoped to specific runs, tasks, tags, or batches. See our [authentication guide](/realtime/auth) for details on creating and using public access tokens.
-
-{" "}
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index 46a49bc049..cb31a0079e 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -58,8 +58,8 @@ Learn more about [generating and managing tokens in our authentication guide](/r
We provide several categories of hooks:
- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
-- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, and streams using real-time updates
-- **[Metadata hooks](/realtime/react-hooks/metadata)** - Subscribe to run metadata updates in React components
+- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, metadata, and more using real-time updates
+- **[Streams hooks](/realtime/react-hooks/streams)** - Subscribe to real-time streams from your tasks
- **[SWR hooks](/realtime/react-hooks/swr)** - Fetch data once and cache it using SWR
## SWR vs Realtime hooks
@@ -71,5 +71,3 @@ We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](ht
configured to poll for updates. But because of rate-limits and the way the Trigger.dev API works,
we recommend using the Realtime hooks for most use-cases.
-
-{" "}
diff --git a/docs/realtime/react-hooks/realtime.mdx b/docs/realtime/react-hooks/realtime.mdx
index 25e4a204a7..586498e7d0 100644
--- a/docs/realtime/react-hooks/realtime.mdx
+++ b/docs/realtime/react-hooks/realtime.mdx
@@ -1,18 +1,25 @@
---
title: Realtime hooks
sidebarTitle: Realtime
-description: Get live updates from the Trigger.dev API in your frontend application.
+description: Get live updates from runs, batches, metadata, and more in your frontend application.
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). Before reading this guide:
+These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). They automatically include real-time updates for run status, metadata, output, and other properties. Before reading this guide:
- Read our [Realtime documentation](/realtime) to understand how the Trigger.dev realtime API works.
- Read how to [setup and authenticate](/realtime/react-hooks) using the `@trigger.dev/react-hooks` package.
## Hooks
+## Triggering + Realtime hooks
+
+For triggering tasks and immediately subscribing to their runs, we provide combo hooks:
+
+- **[`useRealtimeTaskTrigger`](/realtime/react-hooks/triggering#userealtimetasktrigger)** - Trigger a task and subscribe to the run
+- **[`useRealtimeTaskTriggerWithStreams`](/realtime/react-hooks/triggering#userealtimetasktriggerwithstreams)** - Trigger a task and subscribe to both run updates and streams
+
### useRealtimeRun
The `useRealtimeRun` hook allows you to subscribe to a run by its ID.
@@ -194,6 +201,344 @@ export function MyComponent({ batchId }: { batchId: string }) {
See our [Realtime documentation](/realtime) for more information.
+## Using Metadata
+
+All realtime hooks automatically include metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
+
+
+ To learn how to update metadata from your tasks, see our [backend metadata
+ documentation](/realtime/backend/metadata).
+
+
+### Progress monitoring
+
+```tsx
+"use client"; // This is needed for Next.js App Router or other RSC frameworks
+
+import { useRealtimeRun } from "@trigger.dev/react-hooks";
+
+export function ProgressMonitor({
+ runId,
+ publicAccessToken,
+}: {
+ runId: string;
+ publicAccessToken: string;
+}) {
+ const { run, error, isLoading } = useRealtimeRun(runId, {
+ accessToken: publicAccessToken,
+ });
+
+ if (isLoading) return
+ );
+}
+```
+
## Common options
### accessToken & baseURL
diff --git a/docs/realtime/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
index d6dd3a2da3..25705fe3fa 100644
--- a/docs/realtime/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -12,51 +12,6 @@ We provide a set of hooks that can be used to trigger tasks from your frontend a
We've created a [Demo application](https://github.com/triggerdotdev/realtime-llm-battle) that demonstrates how to use our React hooks to trigger tasks in a Next.js application. The application uses the `@trigger.dev/react-hooks` package to trigger a task and subscribe to the run in real-time.
-## Authentication
-
-To authenticate a trigger hook, you must provide a special one-time use "trigger" token. These tokens are very similar to [Public Access Tokens](/realtime/auth), but they can only be used once to trigger a task. You can generate a trigger token using the `auth.createTriggerPublicToken` function in your backend code:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-// Somewhere in your backend code
-const triggerToken = await auth.createTriggerPublicToken("my-task");
-```
-
-These tokens also expire, with the default expiration time being 15 minutes. You can specify a custom expiration time by passing a `expirationTime` parameter:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-// Somewhere in your backend code
-const triggerToken = await auth.createTriggerPublicToken("my-task", {
- expirationTime: "24hr",
-});
-```
-
-You can also pass multiple tasks to the `createTriggerPublicToken` function to create a token that can trigger multiple tasks:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-// Somewhere in your backend code
-const triggerToken = await auth.createTriggerPublicToken(["my-task-1", "my-task-2"]);
-```
-
-You can also pass the `multipleUse` parameter to create a token that can be used multiple times:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-const triggerToken = await auth.createTriggerPublicToken("my-task", {
- multipleUse: true, // β Use this with caution!
-});
-```
-
-
- After generating the trigger token in your backend, you must pass it to your frontend application.
- We have a guide on how to do this in the [React hooks
- overview](/realtime/react-hooks#passing-the-token-to-the-frontend).
-
-
## Hooks
### useTaskTrigger
From d60cfaf51aa2a018910299fd59747d2f9f5310f7 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:33:50 +0100
Subject: [PATCH 05/27] Improved backend docs
---
docs/realtime/backend/metadata.mdx | 4 ----
docs/realtime/backend/overview.mdx | 18 +++++++++---------
docs/realtime/backend/subscribe.mdx | 12 ------------
3 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/docs/realtime/backend/metadata.mdx b/docs/realtime/backend/metadata.mdx
index 71c75592cb..ab2b650049 100644
--- a/docs/realtime/backend/metadata.mdx
+++ b/docs/realtime/backend/metadata.mdx
@@ -219,8 +219,4 @@ async function monitorTypedProgress(runId: string) {
}
```
-## Authentication
-
-Backend metadata subscriptions support both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific run, task, or tag. See our [authentication guide](/realtime/auth) for details.
-
{" "}
diff --git a/docs/realtime/backend/overview.mdx b/docs/realtime/backend/overview.mdx
index 931493b4c4..f13bed6bd3 100644
--- a/docs/realtime/backend/overview.mdx
+++ b/docs/realtime/backend/overview.mdx
@@ -16,6 +16,15 @@ The backend API provides three main categories of functionality:
- **[Metadata](/realtime/backend/metadata)** - Update and subscribe to run metadata in real-time
- **[Streams](/realtime/backend/streams)** - Emit and consume real-time streaming data from your tasks
+## Authentication
+
+All backend functions support both server-side and client-side authentication:
+
+- **Server-side**: Use your API key (automatically handled in tasks)
+- **Client-side**: Generate a Public Access Token with appropriate scopes
+
+See our [authentication guide](/realtime/auth) for detailed information on creating and using tokens.
+
## Quick example
Subscribe to a run:
@@ -51,13 +60,4 @@ export const myTask = task({
});
```
-## Authentication
-
-All backend functions support both server-side and client-side authentication:
-
-- **Server-side**: Use your API key (automatically handled in tasks)
-- **Client-side**: Generate a Public Access Token with appropriate scopes
-
-See our [authentication guide](/realtime/auth) for detailed information on creating and using tokens.
-
{" "}
diff --git a/docs/realtime/backend/subscribe.mdx b/docs/realtime/backend/subscribe.mdx
index 5f9ae34440..70d39b6578 100644
--- a/docs/realtime/backend/subscribe.mdx
+++ b/docs/realtime/backend/subscribe.mdx
@@ -10,8 +10,6 @@ These functions allow you to subscribe to run updates from your backend code. Ea
Subscribes to all changes to a specific run.
-
-
```ts Example
import { runs } from "@trigger.dev/sdk/v3";
@@ -20,8 +18,6 @@ for await (const run of runs.subscribeToRun("run_1234")) {
}
```
-
-
This function subscribes to all changes to a run. It returns an async iterator that yields the run object whenever the run is updated. The iterator will complete when the run is finished.
**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific run. See our [authentication guide](/realtime/auth) for details.
@@ -32,8 +28,6 @@ This function subscribes to all changes to a run. It returns an async iterator t
Subscribes to all changes to runs with a specific tag.
-
-
```ts Example
import { runs } from "@trigger.dev/sdk/v3";
@@ -42,8 +36,6 @@ for await (const run of runs.subscribeToRunsWithTag("user:1234")) {
}
```
-
-
This function subscribes to all changes to runs with a specific tag. It returns an async iterator that yields the run object whenever a run with the specified tag is updated. This iterator will never complete, so you must manually break out of the loop when you no longer want to receive updates.
**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific tag. See our [authentication guide](/realtime/auth) for details.
@@ -54,8 +46,6 @@ This function subscribes to all changes to runs with a specific tag. It returns
Subscribes to all changes for runs in a batch.
-
-
```ts Example
import { runs } from "@trigger.dev/sdk/v3";
@@ -64,8 +54,6 @@ for await (const run of runs.subscribeToBatch("batch_1234")) {
}
```
-
-
This function subscribes to all changes for runs in a batch. It returns an async iterator that yields a run object whenever a run in the batch is updated. The iterator does not complete on its own, you must manually `break` the loop when you want to stop listening for updates.
**Authentication**: This function supports both server-side and client-side authentication. For server-side authentication, use your API key. For client-side authentication, you must generate a public access token with read access to the specific batch. See our [authentication guide](/realtime/auth) for details.
From a6fc9c5a35945dd183557ecabeddd0a42397ec83 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 25 Jul 2025 14:45:10 +0100
Subject: [PATCH 06/27] Fixed broken link
---
docs/realtime/react-hooks/streams.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/realtime/react-hooks/streams.mdx b/docs/realtime/react-hooks/streams.mdx
index b2c79de79e..161b898f27 100644
--- a/docs/realtime/react-hooks/streams.mdx
+++ b/docs/realtime/react-hooks/streams.mdx
@@ -10,7 +10,7 @@ These hooks allow you to consume real-time streams from your tasks. Streams are
To learn how to emit streams from your tasks, see our [backend streams
- documentation](/realtime/backend#streams).
+ documentation](/realtime/backend/streams).
## useRealtimeRunWithStreams
From 1a8cf5b01e165df88e91b56cd28eff4e159551cb Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Mon, 28 Jul 2025 11:14:10 +0100
Subject: [PATCH 07/27] Fixed broken links
---
.../example-projects/batch-llm-evaluator.mdx | 4 +-
.../human-in-the-loop-workflow.mdx | 5 +-
.../vercel-ai-sdk-deep-research.mdx | 2 +-
.../vercel-ai-sdk-image-generator.mdx | 4 +-
docs/introduction.mdx | 126 +++++++++++++-----
docs/management/authentication.mdx | 4 +-
docs/realtime/auth.mdx | 4 +-
docs/runs/metadata.mdx | 2 +-
docs/snippets/realtime-learn-more.mdx | 4 +-
docs/triggering.mdx | 2 +-
docs/video-walkthrough.mdx | 13 +-
docs/wait-for-token.mdx | 2 +-
12 files changed, 121 insertions(+), 51 deletions(-)
diff --git a/docs/guides/example-projects/batch-llm-evaluator.mdx b/docs/guides/example-projects/batch-llm-evaluator.mdx
index c214e80722..4457e5fbba 100644
--- a/docs/guides/example-projects/batch-llm-evaluator.mdx
+++ b/docs/guides/example-projects/batch-llm-evaluator.mdx
@@ -39,11 +39,11 @@ This demo is a full stack example that uses the following:
- View the Trigger.dev task code in the [src/trigger/batch.ts](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/trigger/batch.ts) file.
- The `evaluateModels` task uses the `batch.triggerByTaskAndWait` method to distribute the task to the different LLM models.
- It then passes the results through to a `summarizeEvals` task that calculates some dummy "tags" for each LLM response.
-- We use a [useRealtimeRunsWithTag](https://trigger.dev/docs/frontend/react-hooks/realtime#userealtimerunswithtag) hook to subscribe to the different evaluation tasks runs in the [src/components/llm-evaluator.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/llm-evaluator.tsx) file.
+- We use a [useRealtimeRunsWithTag](/realtime/react-hooks/realtime#userealtimerunswithtag) hook to subscribe to the different evaluation tasks runs in the [src/components/llm-evaluator.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/llm-evaluator.tsx) file.
- We then pass the relevant run down into three different components for the different models:
- The `AnthropicEval` component: [src/components/evals/Anthropic.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/evals/Anthropic.tsx)
- The `XAIEval` component: [src/components/evals/XAI.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/evals/XAI.tsx)
- The `OpenAIEval` component: [src/components/evals/OpenAI.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/evals/OpenAI.tsx)
-- Each of these components then uses [useRealtimeRunWithStreams](https://trigger.dev/docs/frontend/react-hooks/realtime#userealtimerunwithstreams) to subscribe to the different LLM responses.
+- Each of these components then uses [useRealtimeRunWithStreams](/realtime/react-hooks/streams) to subscribe to the different LLM responses.
diff --git a/docs/guides/example-projects/human-in-the-loop-workflow.mdx b/docs/guides/example-projects/human-in-the-loop-workflow.mdx
index 36d5bcc66f..dbc0f6f7cd 100644
--- a/docs/guides/example-projects/human-in-the-loop-workflow.mdx
+++ b/docs/guides/example-projects/human-in-the-loop-workflow.mdx
@@ -79,7 +79,6 @@ await wait.completeToken(
-
While the workflow in this example is static and does not allow changing the connections between nodes in the UI, it serves as a good baseline for understanding how to build completely custom workflow builders using Trigger.dev and ReactFlow.
## Learn more about Trigger.dev Realtime and waitpoint tokens
@@ -87,6 +86,6 @@ While the workflow in this example is static and does not allow changing the con
To learn more, take a look at the following resources:
- [Trigger.dev Realtime](/realtime) - learn more about how to subscribe to runs and get real-time updates
-- [Realtime streaming](/realtime/streams) - learn more about streaming data from your tasks
-- [React hooks](/frontend/react-hooks) - learn more about using React hooks to interact with the Trigger.dev API
+- [Realtime streaming](/realtime/react-hooks/streams) - learn more about streaming data from your tasks
+- [React hooks](/realtime/react-hooks) - learn more about using React hooks to interact with the Trigger.dev API
- [Waitpoint tokens](/wait-for-token) - learn about waitpoint tokens in Trigger.dev and human-in-the-loop flows
diff --git a/docs/guides/example-projects/vercel-ai-sdk-deep-research.mdx b/docs/guides/example-projects/vercel-ai-sdk-deep-research.mdx
index aa0d54687c..33c58925ed 100644
--- a/docs/guides/example-projects/vercel-ai-sdk-deep-research.mdx
+++ b/docs/guides/example-projects/vercel-ai-sdk-deep-research.mdx
@@ -110,7 +110,7 @@ Level 0 (Initial Query): "AI safety in autonomous vehicles"
### Using Trigger.dev Realtime to trigger and subscribe to the deep research task
-We use the [`useRealtimeTaskTrigger`](/frontend/react-hooks/triggering#userealtimetasktrigger) React hook to trigger the `deep-research` task and subscribe to it's updates.
+We use the [`useRealtimeTaskTrigger`](/realtime/react-hooks/triggering#userealtimetasktrigger) React hook to trigger the `deep-research` task and subscribe to it's updates.
**Frontend (React Hook)**:
diff --git a/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx b/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
index 15eda0270a..a4a1661224 100644
--- a/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
+++ b/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
@@ -11,7 +11,7 @@ import RealtimeLearnMore from "/snippets/realtime-learn-more.mdx";
This demo is a full stack example that uses the following:
- A [Next.js](https://nextjs.org/) app using [shadcn](https://ui.shadcn.com/) for the UI
-- Our 'useRealtimeRun' [React hook](https://trigger.dev/docs/frontend/react-hooks/realtime) to subscribe to the run and show updates on the frontend
+- Our 'useRealtimeRun' [React hook](/realtime/react-hooks/realtime) to subscribe to the run and show updates on the frontend
- The [Vercel AI SDK](https://sdk.vercel.ai/docs/introduction) to [generate images](https://sdk.vercel.ai/docs/ai-sdk-core/image-generation) using OpenAI's DALL-E models
## GitHub repo
@@ -36,6 +36,6 @@ This demo is a full stack example that uses the following:
## Relevant code
- View the Trigger.dev task code which generates the image using the Vercel AI SDK in [src/trigger/realtime-generate-image.ts](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/trigger/realtime-generate-image.ts).
-- We use a [useRealtimeRun](https://trigger.dev/docs/frontend/react-hooks/realtime#userealtimerun) hook to subscribe to the run in [src/app/processing/[id]/ProcessingContent.tsx](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/app/processing/[id]/ProcessingContent.tsx).
+- We use a [useRealtimeRun](/realtime/react-hooks/realtime#userealtimerun) hook to subscribe to the run in [src/app/processing/[id]/ProcessingContent.tsx](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/app/processing/[id]/ProcessingContent.tsx).
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
index c8ed0f3480..5a0cd9f624 100644
--- a/docs/introduction.mdx
+++ b/docs/introduction.mdx
@@ -12,7 +12,11 @@ mode: "center"
Explore dozens of examples tasks to use in your own projects
-
+
Learn how to use Trigger.dev with your favorite frameworks
@@ -24,7 +28,7 @@ mode: "center"
Trigger.dev is an open source background jobs framework that lets you write reliable workflows in plain async code. Run long-running AI tasks, handle complex background jobs, and build AI agents with built-in queuing, automatic retries, and real-time monitoring. No timeouts, elastic scaling, and zero infrastructure management required.
-We provide everything you need to build and manage background tasks: a CLI and SDK for writing tasks in your existing codebase, support for both [regular](/tasks/overview) and [scheduled](/tasks/scheduled) tasks, full observability through our dashboard, and a [Realtime API](/realtime) with [React hooks](/frontend/react-hooks#realtime-hooks) for showing task status in your frontend. You can use [Trigger.dev Cloud](https://cloud.trigger.dev) or [self-host](/open-source-self-hosting) on your own infrastructure.
+We provide everything you need to build and manage background tasks: a CLI and SDK for writing tasks in your existing codebase, support for both [regular](/tasks/overview) and [scheduled](/tasks/scheduled) tasks, full observability through our dashboard, and a [Realtime API](/realtime) with [React hooks](/realtime/react-hooks#realtime-hooks) for showing task status in your frontend. You can use [Trigger.dev Cloud](https://cloud.trigger.dev) or [self-host](/open-source-self-hosting) on your own infrastructure.
## Learn the concepts
@@ -39,7 +43,8 @@ We provide everything you need to build and manage background tasks: a CLI and S
Runs are the instances of tasks that are executed. Learn how they work.
- API keys are used to authenticate requests to the Trigger.dev API. Learn how to create and use them.
+ API keys are used to authenticate requests to the Trigger.dev API. Learn how to create and use
+ them.
@@ -52,13 +57,18 @@ We provide everything you need to build and manage background tasks: a CLI and S
The Realtime API allows you to trigger tasks and get the status of runs.
-
+
React hooks are a way to show task status in your frontend.
Waits are a way to wait for a task to finish before continuing.
-
+
Learn how to handle errors and retries.
@@ -69,37 +79,89 @@ We provide everything you need to build and manage background tasks: a CLI and S
## Explore by example
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
## Explore by build extension
-| Extension | What it does | Docs |
-|:----------|:------------|:--------------|
-| prismaExtension | Use Prisma with Trigger.dev | [Learn more](/config/extensions/prismaExtension) |
-| pythonExtension | Execute Python scripts in Trigger.dev | [Learn more](/config/extensions/pythonExtension) |
-| puppeteer | Use Puppeteer with Trigger.dev | [Learn more](/config/extensions/puppeteer) |
-| ffmpeg | Use FFmpeg with Trigger.dev | [Learn more](/config/extensions/ffmpeg) |
-| aptGet | Install system packages with aptGet | [Learn more](/config/extensions/aptGet) |
-| additionalFiles | Copy additional files to the build directory | [Learn more](/config/extensions/additionalFiles) |
-| additionalPackages | Include additional packages in the build | [Learn more](/config/extensions/additionalPackages) |
-| syncEnvVars | Automatically sync environment variables to Trigger.dev | [Learn more](/config/extensions/syncEnvVars) |
-| esbuildPlugin | Add existing or custom esbuild plugins to your build process | [Learn more](/config/extensions/esbuildPlugin) |
-| emitDecoratorMetadata | Support for the emitDecoratorMetadata TypeScript compiler | [Learn more](/config/extensions/emitDecoratorMetadata) |
-| audioWaveform | Support for Audio Waveform in your project | [Learn more](/config/extensions/audioWaveform) |
+| Extension | What it does | Docs |
+| :-------------------- | :----------------------------------------------------------- | :----------------------------------------------------- |
+| prismaExtension | Use Prisma with Trigger.dev | [Learn more](/config/extensions/prismaExtension) |
+| pythonExtension | Execute Python scripts in Trigger.dev | [Learn more](/config/extensions/pythonExtension) |
+| puppeteer | Use Puppeteer with Trigger.dev | [Learn more](/config/extensions/puppeteer) |
+| ffmpeg | Use FFmpeg with Trigger.dev | [Learn more](/config/extensions/ffmpeg) |
+| aptGet | Install system packages with aptGet | [Learn more](/config/extensions/aptGet) |
+| additionalFiles | Copy additional files to the build directory | [Learn more](/config/extensions/additionalFiles) |
+| additionalPackages | Include additional packages in the build | [Learn more](/config/extensions/additionalPackages) |
+| syncEnvVars | Automatically sync environment variables to Trigger.dev | [Learn more](/config/extensions/syncEnvVars) |
+| esbuildPlugin | Add existing or custom esbuild plugins to your build process | [Learn more](/config/extensions/esbuildPlugin) |
+| emitDecoratorMetadata | Support for the emitDecoratorMetadata TypeScript compiler | [Learn more](/config/extensions/emitDecoratorMetadata) |
+| audioWaveform | Support for Audio Waveform in your project | [Learn more](/config/extensions/audioWaveform) |
## Getting help
diff --git a/docs/management/authentication.mdx b/docs/management/authentication.mdx
index 2d24c1f354..701a017fcb 100644
--- a/docs/management/authentication.mdx
+++ b/docs/management/authentication.mdx
@@ -8,7 +8,7 @@ There are two methods of authenticating with the management API: using a secret
There is a separate authentication strategy when making requests from your frontend application.
- See the [Frontend guide](/frontend/overview) for more information. This guide is for backend usage
+ See the [Realtime guide](/realtime/overview) for more information. This guide is for backend usage
only.
@@ -94,4 +94,4 @@ await envvars.upload("proj_1234", "dev", {
},
override: true,
});
-```
\ No newline at end of file
+```
diff --git a/docs/realtime/auth.mdx b/docs/realtime/auth.mdx
index dd6af13ca8..0176278b47 100644
--- a/docs/realtime/auth.mdx
+++ b/docs/realtime/auth.mdx
@@ -1,6 +1,6 @@
---
-title: Authentication
-sidebarTitle: Authentication
+title: Realtime authentication
+sidebarTitle: Realtime authentication
description: Authenticating real-time API requests with Public Access Tokens
---
diff --git a/docs/runs/metadata.mdx b/docs/runs/metadata.mdx
index 87c648b9a0..e6b2caf0b9 100644
--- a/docs/runs/metadata.mdx
+++ b/docs/runs/metadata.mdx
@@ -264,7 +264,7 @@ export const myTask = task({
### stream
-Capture a stream of values and make the stream available when using Realtime. See our [Realtime streams](/realtime/streams) documentation for more information.
+Capture a stream of values and make the stream available when using Realtime. See our [Realtime streams](/realtime/react-hooks/streams) documentation for more information.
```ts
import { task, metadata } from "@trigger.dev/sdk/v3";
diff --git a/docs/snippets/realtime-learn-more.mdx b/docs/snippets/realtime-learn-more.mdx
index 9cad1534d9..c9b2ef2bd2 100644
--- a/docs/snippets/realtime-learn-more.mdx
+++ b/docs/snippets/realtime-learn-more.mdx
@@ -3,6 +3,6 @@
To learn more, take a look at the following resources:
- [Trigger.dev Realtime](/realtime) - learn more about how to subscribe to runs and get real-time updates
-- [Realtime streaming](/realtime/streams) - learn more about streaming data from your tasks
+- [Realtime streaming](/realtime/react-hooks/streams) - learn more about streaming data from your tasks
- [Batch Triggering](/triggering#tasks-batchtrigger) - learn more about how to trigger tasks in batches
-- [React hooks](/frontend/react-hooks) - learn more about using React hooks to interact with the Trigger.dev API
+- [React hooks](/realtime/react-hooks) - learn more about using React hooks to interact with the Trigger.dev API
diff --git a/docs/triggering.mdx b/docs/triggering.mdx
index 235383796f..6986d8ffe2 100644
--- a/docs/triggering.mdx
+++ b/docs/triggering.mdx
@@ -704,7 +704,7 @@ export const childTask2 = task({
## Triggering from your frontend
If you want to trigger a task directly from a frontend application, you can use our [React
-hooks](/frontend/react-hooks/triggering).
+hooks](/realtime/react-hooks/triggering).
## Options
diff --git a/docs/video-walkthrough.mdx b/docs/video-walkthrough.mdx
index f172860b30..7da8e3f47e 100644
--- a/docs/video-walkthrough.mdx
+++ b/docs/video-walkthrough.mdx
@@ -3,12 +3,21 @@ title: "Video walkthrough"
description: "Go from zero to a working task in your Next.js app in 10 minutes."
---
-
+{" "}
+
### In this video we cover the following topics:
- [0:00](https://youtu.be/YH_4c0K7fGM?si=J8svVzotZtyTXDap&t=0) β [Install Trigger.dev](/quick-start) in an existing Next.js project
- [1:44](https://youtu.be/YH_4c0K7fGM?si=J8svVzotZtyTXDap&t=104) β [Run and test](/run-tests) the "Hello, world!" example project
- [2:09](https://youtu.be/YH_4c0K7fGM?si=FMTP8ep_cDBCU0_x&t=128) β Create and run an AI image generation task that uses [Fal.ai](https://fal.ai) β ([View the code](/guides/examples/fal-ai-image-to-cartoon))
-- [6:25](https://youtu.be/YH_4c0K7fGM?si=pPc8iLI2Y9FGD3yo&t=385) β Create and run a [Realtime](/realtime/overview) example using [React hooks](/frontend/react-hooks) β ([View the code](/guides/examples/fal-ai-realtime))
+- [6:25](https://youtu.be/YH_4c0K7fGM?si=pPc8iLI2Y9FGD3yo&t=385) β Create and run a [Realtime](/realtime/overview) example using [React hooks](/realtime/react-hooks) β ([View the code](/guides/examples/fal-ai-realtime))
- [11:10](https://youtu.be/YH_4c0K7fGM?si=Mjd0EvvNsNlVouvY&t=670) β [Deploy your task](/cli-deploy) to the Trigger.dev Cloud
diff --git a/docs/wait-for-token.mdx b/docs/wait-for-token.mdx
index 8098243dfd..34be646064 100644
--- a/docs/wait-for-token.mdx
+++ b/docs/wait-for-token.mdx
@@ -125,7 +125,7 @@ The JSON body of the POST request will be used as the output of the token. If th
A Public Access Token that can be used to complete the token from a client-side application (or
- another backend). See our [frontend docs](/frontend/overview) for more details.
+ another backend). See our [Realtime docs](/realtime/auth) for more details.
### Example
From fd37ce7504570d8ad9a14f0ecc5a602e384b73f6 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 14:09:05 +0100
Subject: [PATCH 08/27] Updated the structure
---
docs/docs.json | 2 +-
docs/realtime/auth.mdx | 120 ++++++------------
docs/realtime/overview.mdx | 27 ++--
.../{realtime.mdx => subscribe.mdx} | 4 +-
docs/realtime/react-hooks/triggering.mdx | 9 +-
5 files changed, 64 insertions(+), 98 deletions(-)
rename docs/realtime/react-hooks/{realtime.mdx => subscribe.mdx} (99%)
diff --git a/docs/docs.json b/docs/docs.json
index ee8b3f700f..ffc384eb09 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -123,7 +123,7 @@
"pages": [
"realtime/react-hooks/overview",
"realtime/react-hooks/triggering",
- "realtime/react-hooks/realtime",
+ "realtime/react-hooks/subscribe",
"realtime/react-hooks/streams",
"realtime/react-hooks/swr"
]
diff --git a/docs/realtime/auth.mdx b/docs/realtime/auth.mdx
index 0176278b47..6698cc06e1 100644
--- a/docs/realtime/auth.mdx
+++ b/docs/realtime/auth.mdx
@@ -1,12 +1,23 @@
---
title: Realtime authentication
-sidebarTitle: Realtime authentication
-description: Authenticating real-time API requests with Public Access Tokens
+sidebarTitle: Realtime auth
+description: Authenticating real-time API requests with Public Access Tokens or Trigger Tokens
---
-To use the Realtime API, you need to authenticate your requests with Public Access Tokens. These tokens provide secure, scoped access to your runs and can be used in both frontend and backend applications.
+To use the Realtime API, you need to authenticate your requests with Public Access Tokens or Trigger Tokens. These tokens provide secure, scoped access to your runs and can be used in both frontend and backend applications.
-## Creating Public Access Tokens
+## Token Types
+
+There are two types of tokens you can use with the Realtime API:
+
+- **[Public Access Tokens](#public-access-tokens-for-subscribing-to-runs)** - Used to read and subscribe to run data. Can be used in both frontend and backend applications.
+- **[Trigger Tokens](#trigger-tokens-for-frontend-triggering-only)** - Used to trigger tasks from your frontend. These are more secure, single-use tokens that can only be used in frontend applications.
+
+## Public Access Tokens (for subscribing to runs)
+
+Public Access Tokens are used to read and subscribe to run data. They can be used in both frontend and backend applications to subscribe to runs.
+
+### Creating Public Access Tokens
You can create a Public Access Token using the `auth.createPublicToken` function in your **backend** code:
@@ -16,7 +27,7 @@ import { auth } from "@trigger.dev/sdk/v3";
const publicToken = await auth.createPublicToken(); // π this public access token has no permissions, so is pretty useless!
```
-## Scopes
+### Scopes
By default a Public Access Token has no permissions. You must specify the scopes you need when creating a Public Access Token:
@@ -103,7 +114,7 @@ const publicToken = await auth.createPublicToken({
});
```
-## Expiration
+### Expiration
By default, Public Access Token's expire after 15 minutes. You can specify a different expiration time when creating a Public Access Token:
@@ -121,55 +132,28 @@ const publicToken = await auth.createPublicToken({
The format used for a time span is the same as the [jose package](https://github.com/panva/jose), which is a number followed by a unit. Valid units are: "sec", "secs", "second", "seconds", "s", "minute", "minutes", "min", "mins", "m", "hour", "hours", "hr", "hrs", "h", "day", "days", "d", "week", "weeks", "w", "year", "years", "yr", "yrs", and "y". It is not possible to specify months. 365.25 days is used as an alias for a year. If the string is suffixed with "ago", or prefixed with a "-", the resulting time span gets subtracted from the current unix timestamp. A "from now" suffix can also be used for readability when adding to the current unix timestamp.
-## Auto-generated tokens
+### Auto-generated tokens
-When triggering a task from your backend, the `handle` received from the `trigger` function now includes a `publicAccessToken` field. This token can be used to authenticate requests in your frontend application:
+When you [trigger tasks](/triggering) from your backend, the `handle` received includes a `publicAccessToken` field. This token can be used to authenticate real-time requests in your frontend application.
-```ts
-import { tasks } from "@trigger.dev/sdk/v3";
+By default, auto-generated tokens expire after 15 minutes and have a read scope for the specific run(s) that were triggered. You can customize the expiration by passing a `publicTokenOptions` object to the trigger function.
-const handle = await tasks.trigger("my-task", { some: "data" });
+See our [triggering documentation](/triggering) for detailed examples of how to trigger tasks and get auto-generated tokens.
-console.log(handle.publicAccessToken);
-```
+### Subscribing to runs with Public Access Tokens
-By default, tokens returned from the `trigger` function expire after 15 minutes and have a read scope for that specific run. You can customize the expiration of the auto-generated tokens by passing a `publicTokenOptions` object to the `trigger` function:
+Once you have a Public Access Token, you can use it to authenticate requests to the Realtime API in both backend and frontend applications.
-```ts
-import { tasks } from "@trigger.dev/sdk/v3";
+**Backend usage:** See our [backend subscription documentation](/realtime/backend/subscribe) for examples of using tokens with backend functions.
-const handle = await tasks.trigger(
- "my-task",
- { some: "data" },
- {
- tags: ["my-tag"],
- },
- {
- publicAccessToken: {
- expirationTime: "1hr",
- },
- }
-);
-```
+**Frontend usage:** See our [React hooks documentation](/realtime/react-hooks) for examples of using tokens with frontend components.
-You will also get back a Public Access Token when using the `batchTrigger` function:
-
-```ts
-import { tasks } from "@trigger.dev/sdk/v3";
-
-const handle = await tasks.batchTrigger("my-task", [
- { payload: { some: "data" } },
- { payload: { some: "data" } },
- { payload: { some: "data" } },
-]);
-
-console.log(handle.publicAccessToken);
-```
-
-## Trigger tokens
+## Trigger Tokens (for frontend triggering only)
For triggering tasks from your frontend, you need special "trigger" tokens. These tokens can only be used once to trigger a task and are more secure than regular Public Access Tokens.
+### Creating Trigger Tokens
+
```ts
import { auth } from "@trigger.dev/sdk/v3";
@@ -177,16 +161,7 @@ import { auth } from "@trigger.dev/sdk/v3";
const triggerToken = await auth.createTriggerPublicToken("my-task");
```
-These tokens also expire, with the default expiration time being 15 minutes. You can specify a custom expiration time:
-
-```ts
-import { auth } from "@trigger.dev/sdk/v3";
-
-// Somewhere in your backend code
-const triggerToken = await auth.createTriggerPublicToken("my-task", {
- expirationTime: "24hr",
-});
-```
+### Multiple tasks
You can pass multiple tasks to create a token that can trigger multiple tasks:
@@ -197,6 +172,8 @@ import { auth } from "@trigger.dev/sdk/v3";
const triggerToken = await auth.createTriggerPublicToken(["my-task-1", "my-task-2"]);
```
+### Multiple use
+
You can also create tokens that can be used multiple times:
```ts
@@ -208,36 +185,21 @@ const triggerToken = await auth.createTriggerPublicToken("my-task", {
});
```
-## Using tokens
+### Expiration
-Once you have a Public Access Token, you can use it to authenticate requests to the Realtime API:
-
-### Backend usage
+These tokens also expire, with the default expiration time being 15 minutes. You can specify a custom expiration time:
```ts
-import { runs } from "@trigger.dev/sdk/v3";
-
-// Using the token with backend functions
-for await (const run of runs.subscribeToRun("run_1234", {
- accessToken: publicToken,
-})) {
- console.log(run);
-}
-```
-
-### Frontend usage
+import { auth } from "@trigger.dev/sdk/v3";
-```tsx
-import { useRealtimeRun } from "@trigger.dev/react-hooks";
+// Somewhere in your backend code
+const triggerToken = await auth.createTriggerPublicToken("my-task", {
+ expirationTime: "24hr",
+});
+```
-export function MyComponent({ runId, publicAccessToken }) {
- const { run, error } = useRealtimeRun(runId, {
- accessToken: publicAccessToken,
- });
+### Triggering tasks from frontend with Trigger Tokens
- if (error) return
Error: {error.message}
;
- return
Run: {run?.id}
;
-}
-```
+To trigger tasks from your frontend, you need to use special Trigger Tokens created in your backend. See our [React hooks triggering documentation](/realtime/react-hooks/triggering) for complete examples.
See our [React hooks documentation](/realtime/react-hooks) for more details on using hooks in your frontend application.
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 9a74bbee0c..32f49f3a6d 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -6,9 +6,18 @@ description: Using the Trigger.dev Realtime API to subscribe to runs in real-tim
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-Trigger.dev Realtime allows you subscribe to runs and get real-time updates as they execute. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
+Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time updates for runs. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
-## What you can subscribe to
+## Authentication
+
+All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for details on:
+
+- Creating Public Access Tokens to subscribe to runs
+- Creating Trigger Tokens to trigger tasks from your frontend
+- Scoping tokens to specific runs, tasks, tags, or batches
+- Auto-generated tokens from `tasks.trigger()`
+
+## How run subscriptions work
You can subscribe to real-time updates for:
@@ -17,7 +26,7 @@ You can subscribe to real-time updates for:
- **Task runs** - All runs for specific tasks
- **Batch runs** - All runs in a batch
-You automatically receive the complete [run object](/realtime/run-object) containing status, timestamps, metadata, tags, and more whenever:
+When you subscribe to runs, you automatically receive the complete [run object](/realtime/run-object) containing status, timestamps, metadata, tags, and more whenever:
- Run status changes (queued β executing β completed, etc.)
- [Run metadata](/runs/metadata) is updated
@@ -29,23 +38,15 @@ Your tasks can also send additional custom data:
- **Metadata updates** - Update custom metadata on runs that gets streamed to subscribers ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/realtime#using-metadata))
- **Stream function** - Stream data chunks in real-time, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
-## Authentication
-
-All Realtime subscriptions require authentication. See our [authentication guide](/realtime/auth) for details on:
-
-- Creating Public Access Tokens for frontend use
-- Scoping tokens to specific runs, tasks, tags, or batches
-- Auto-generated tokens from `tasks.trigger()`
-
## Implementation approaches
-### Backend subscriptions
+### Backend implementation
Use our server-side SDK to subscribe to runs from your backend code, other tasks, or serverless functions. Perfect for triggering workflows, sending notifications, or updating databases based on run status changes.
β **[See Backend functions guide](/realtime/backend)**
-### Frontend subscriptions
+### Frontend implementation
Use our React hooks to build real-time UIs that update as runs execute. Ideal for progress bars, status indicators, and live dashboards.
diff --git a/docs/realtime/react-hooks/realtime.mdx b/docs/realtime/react-hooks/subscribe.mdx
similarity index 99%
rename from docs/realtime/react-hooks/realtime.mdx
rename to docs/realtime/react-hooks/subscribe.mdx
index 586498e7d0..eaead73567 100644
--- a/docs/realtime/react-hooks/realtime.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -1,6 +1,6 @@
---
-title: Realtime hooks
-sidebarTitle: Realtime
+title: Subscribing to runs
+sidebarTitle: Subscribe
description: Get live updates from runs, batches, metadata, and more in your frontend application.
---
diff --git a/docs/realtime/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
index 25705fe3fa..f1349780c7 100644
--- a/docs/realtime/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -8,9 +8,12 @@ import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
We provide a set of hooks that can be used to trigger tasks from your frontend application.
-## Demo
-
-We've created a [Demo application](https://github.com/triggerdotdev/realtime-llm-battle) that demonstrates how to use our React hooks to trigger tasks in a Next.js application. The application uses the `@trigger.dev/react-hooks` package to trigger a task and subscribe to the run in real-time.
+
+ For triggering tasks from your frontend, you need to use βtriggerβ tokens. These can only be used
+ once to trigger a task and are more secure than regular Public Access Tokens. To learn more about
+ how to create and use these tokens, see our [Trigger Tokens](/realtime/auth#trigger-tokens)
+ documentation.
+
## Hooks
From f57581ea2e90e2cd5c5659f7d5dd7a97ea6676a1 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 15:00:31 +0100
Subject: [PATCH 09/27] Restructured overview
---
docs/realtime/backend/overview.mdx | 19 ------------
docs/realtime/overview.mdx | 50 +++++++++++-------------------
2 files changed, 18 insertions(+), 51 deletions(-)
diff --git a/docs/realtime/backend/overview.mdx b/docs/realtime/backend/overview.mdx
index f13bed6bd3..9b11275122 100644
--- a/docs/realtime/backend/overview.mdx
+++ b/docs/realtime/backend/overview.mdx
@@ -41,23 +41,4 @@ for await (const run of runs.subscribeToRun(handle.id)) {
}
```
-Stream data from a task:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const myTask = task({
- id: "my-task",
- run: async (payload) => {
- // Stream real-time data
- const stream = await metadata.stream("openai", openaiCompletion);
-
- // Process the stream
- for await (const chunk of stream) {
- console.log("Streaming chunk:", chunk);
- }
- },
-});
-```
-
{" "}
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 32f49f3a6d..6d764775ba 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -1,7 +1,7 @@
---
title: Realtime overview
sidebarTitle: Overview
-description: Using the Trigger.dev Realtime API to subscribe to runs in real-time.
+description: Using the Trigger.dev Realtime API to trigger and subscribe to runs in real-time.
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
@@ -10,51 +10,37 @@ Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time upda
## Authentication
-All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for details on:
-
-- Creating Public Access Tokens to subscribe to runs
-- Creating Trigger Tokens to trigger tasks from your frontend
-- Scoping tokens to specific runs, tasks, tags, or batches
-- Auto-generated tokens from `tasks.trigger()`
+All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
## How run subscriptions work
-You can subscribe to real-time updates for:
-
-- **Specific runs** - Monitor individual run progress
-- **Runs with specific tags** - Track runs by category or user
-- **Task runs** - All runs for specific tasks
-- **Batch runs** - All runs in a batch
-
-When you subscribe to runs, you automatically receive the complete [run object](/realtime/run-object) containing status, timestamps, metadata, tags, and more whenever:
+You can subscribe to real-time updates for different scopes of runs:
-- Run status changes (queued β executing β completed, etc.)
-- [Run metadata](/runs/metadata) is updated
-- [Run tags](/tags) are added or removed
-- [Stream data](/realtime/backend#streams) is emitted
+- **Specific runs** - Monitor individual run progress by run ID
+- **Runs with specific tags** - Track all runs that have certain [tags](/tags) (e.g., all runs tagged with `user:123`)
+- **Batch runs** - All runs within a specific batch
+- **Trigger + subscribe combos** - Trigger a task and immediately subscribe to its run (frontend only)
-Your tasks can also send additional custom data:
+Once subscribed, you'll receive the complete [run object](/realtime/run-object) with automatic real-time updates whenever the run changes, including:
-- **Metadata updates** - Update custom metadata on runs that gets streamed to subscribers ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/realtime#using-metadata))
-- **Stream function** - Stream data chunks in real-time, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
+- **Status changes** - queued β executing β completed, etc.
+- **Metadata updates** - Custom progress tracking, status updates, user data, etc. ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/realtime#using-metadata))
+- **Tag changes** - When [tags](/tags) are added or removed from the run
+- **Stream data** - Real-time data chunks from your tasks, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
-## Implementation approaches
-
-### Backend implementation
-
-Use our server-side SDK to subscribe to runs from your backend code, other tasks, or serverless functions. Perfect for triggering workflows, sending notifications, or updating databases based on run status changes.
-
-β **[See Backend functions guide](/realtime/backend)**
+## Realtime approaches
### Frontend implementation
Use our React hooks to build real-time UIs that update as runs execute. Ideal for progress bars, status indicators, and live dashboards.
-β **[See React hooks guide](/realtime/react-hooks)**
+β **[See our React hooks guide](/realtime/react-hooks)**
-## Technical details
+### Backend implementation
+
+Use our server-side SDK to subscribe to runs from your backend code, other tasks, or serverless functions. Perfect for triggering workflows, sending notifications, or updating databases based on run status changes.
-Learn more about the underlying technology and run object structure in our [How it Works](/realtime/how-it-works) guide.
+β **[See our Backend guide](/realtime/backend)**
## Realtime demo
From 048ec36299d4def58c1d6351e6f162b7cdce47cd Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 15:09:12 +0100
Subject: [PATCH 10/27] Updated examples cards
---
docs/snippets/realtime-examples-cards.mdx | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/snippets/realtime-examples-cards.mdx b/docs/snippets/realtime-examples-cards.mdx
index 9cfaa80576..6be059621c 100644
--- a/docs/snippets/realtime-examples-cards.mdx
+++ b/docs/snippets/realtime-examples-cards.mdx
@@ -1,6 +1,14 @@
## Examples
+
+ A chatbot using the AI SDK that demonstrates Anthropic Claude 3.7's thinking capabilities through the Realtime API and
+ react hooks.
+
-
- A chatbot that demonstrates Claude 3.7's thinking capabilities through the Realtime API and
- react hooks.
-
From b6d97e7687c1833b941d7b3a0d0fd802bd927ce3 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 15:43:34 +0100
Subject: [PATCH 11/27] Improved overview
---
docs/realtime/overview.mdx | 24 +++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 6d764775ba..a2aa9b0ad1 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -1,7 +1,7 @@
---
title: Realtime overview
sidebarTitle: Overview
-description: Using the Trigger.dev Realtime API to trigger and subscribe to runs in real-time.
+description: Using the Trigger.dev Realtime API to trigger and/or subscribe to runs in real-time.
---
import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
@@ -12,7 +12,7 @@ Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time upda
All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
-## How run subscriptions work
+## What you can do with Realtime
You can subscribe to real-time updates for different scopes of runs:
@@ -21,12 +21,12 @@ You can subscribe to real-time updates for different scopes of runs:
- **Batch runs** - All runs within a specific batch
- **Trigger + subscribe combos** - Trigger a task and immediately subscribe to its run (frontend only)
-Once subscribed, you'll receive the complete [run object](/realtime/run-object) with automatic real-time updates whenever the run changes, including:
+Once subscribed, you'll receive the complete [run object](/realtime/run-object) with automatic real-time updates whenever the [run changes](/realtime/how-it-works#run-changes), including:
- **Status changes** - queued β executing β completed, etc.
-- **Metadata updates** - Custom progress tracking, status updates, user data, etc. ([backend](/realtime/backend/metadata) | [React hooks](/realtime/react-hooks/realtime#using-metadata))
+- **Metadata updates** - Custom progress tracking, status updates, user data, etc. ([React hooks](/realtime/react-hooks/subscribe#using-metadata) | [backend](/realtime/backend/metadata))
- **Tag changes** - When [tags](/tags) are added or removed from the run
-- **Stream data** - Real-time data chunks from your tasks, perfect for AI/LLM streaming ([backend](/realtime/backend/streams) | [React hooks](/realtime/react-hooks/streams))
+- **Stream data** - Real-time data chunks from your tasks, perfect for AI/LLM streaming ([React hooks](/realtime/react-hooks/streams) | [backend](/realtime/backend/streams))
## Realtime approaches
@@ -41,17 +41,3 @@ Use our React hooks to build real-time UIs that update as runs execute. Ideal fo
Use our server-side SDK to subscribe to runs from your backend code, other tasks, or serverless functions. Perfect for triggering workflows, sending notifications, or updating databases based on run status changes.
β **[See our Backend guide](/realtime/backend)**
-
-## Realtime demo
-
-
-
-
From 8849168a2d6f580d52521f0f8c9cdf13f262b832 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:08:52 +0100
Subject: [PATCH 12/27] Updated how it works
---
docs/realtime/how-it-works.mdx | 67 +++++++++++++++++-----------------
1 file changed, 34 insertions(+), 33 deletions(-)
diff --git a/docs/realtime/how-it-works.mdx b/docs/realtime/how-it-works.mdx
index ed839eee25..594b9da926 100644
--- a/docs/realtime/how-it-works.mdx
+++ b/docs/realtime/how-it-works.mdx
@@ -1,7 +1,7 @@
---
title: How it works
sidebarTitle: How it works
-description: Technical details about the Trigger.dev Realtime API
+description: Technical details about how the Trigger.dev Realtime API works
---
## Architecture
@@ -18,74 +18,75 @@ You will receive updates whenever a run changes for the following reasons:
## Run object
-The run object returned by realtime subscriptions is optimized for streaming updates and differs from the management API's run object. See the [run object reference](/realtime/run-object) for the complete schema and field descriptions.
+The run object returned by Realtime subscriptions is optimized for streaming updates and differs from the management API's run object. See [the run object](/realtime/run-object) page for the complete schema and field descriptions.
-## Type-safety
+## Basic usage
-You can infer the types of the run's payload and output by passing the type of the task to the `subscribeToRun` function. This will give you type-safe access to the run's payload and output.
+After you trigger a task, you can subscribe to the run using the `runs.subscribeToRun` function. This function returns an async iterator that you can use to get updates on the run status.
```ts
import { runs, tasks } from "@trigger.dev/sdk/v3";
-import type { myTask } from "./trigger/my-task";
// Somewhere in your backend code
async function myBackend() {
const handle = await tasks.trigger("my-task", { some: "data" });
- for await (const run of runs.subscribeToRun(handle.id)) {
+ for await (const run of runs.subscribeToRun(handle.id)) {
// This will log the run every time it changes
- console.log(run.payload.some);
-
- if (run.output) {
- // This will log the output if it exists
- console.log(run.output.some);
- }
+ console.log(run);
}
}
```
-When using `subscribeToRunsWithTag`, you can pass a union of task types for all the possible tasks that can have the tag.
+Every time the run changes, the async iterator will yield the updated run. You can use this to update your UI, log the run status, or take any other action.
+
+Alternatively, you can subscribe to changes to any run that includes a specific tag (or tags) using the `runs.subscribeToRunsWithTag` function.
```ts
import { runs } from "@trigger.dev/sdk/v3";
-import type { myTask, myOtherTask } from "./trigger/my-task";
// Somewhere in your backend code
-for await (const run of runs.subscribeToRunsWithTag("my-tag")) {
- // You can narrow down the type based on the taskIdentifier
- switch (run.taskIdentifier) {
- case "my-task": {
- console.log("Run output:", run.output.foo); // This will be type-safe
- break;
- }
- case "my-other-task": {
- console.log("Run output:", run.output.bar); // This will be type-safe
- break;
- }
- }
+for await (const run of runs.subscribeToRunsWithTag("user:1234")) {
+ // This will log the run every time it changes, for all runs with the tag "user:1234"
+ console.log(run);
+}
+```
+
+If you've used `batchTrigger` to trigger multiple runs, you can also subscribe to changes to all the runs triggered in the batch using the `runs.subscribeToBatch` function.
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+
+// Somewhere in your backend code
+for await (const run of runs.subscribeToBatch("batch-id")) {
+ // This will log the run every time it changes, for all runs in the batch with the ID "batch-id"
+ console.log(run);
}
```
## Run metadata
-The run metadata API gives you the ability to add or update custom metadata on a run, which will cause the run to be updated. This allows you to extend the realtime API with custom data attached to a run that can be used for various purposes. Some common use cases include:
+The run metadata API gives you the ability to add or update custom metadata on a run, which will cause the run to be updated. This allows you to extend the Realtime API with custom data attached to a run that can be used for various purposes. Some common use cases include:
- Adding a link to a related resource
- Adding a reference to a user or organization
- Adding a custom status with progress information
-See our [run metadata docs](/runs/metadata) for more on how to use this feature.
+See our [run metadata docs](/runs/metadata) for more on how to write tasks that use the metadata API.
-### Using w/Realtime & React hooks
+### Using metadata with Realtime & React hooks
-We suggest combining run metadata with the realtime API and our [React hooks](/realtime/react-hooks) to bridge the gap between your trigger.dev tasks and your UI. This allows you to update your UI in real-time based on changes to the run metadata. As a simple example, you could add a custom status to a run with a progress value, and update your UI based on that progress.
+You can combine run metadata with the Realtime API to bridge the gap between your trigger.dev tasks and your applications in two ways:
-We have a full demo app repo available [here](https://github.com/triggerdotdev/nextjs-realtime-simple-demo)
+1. Using our [React hooks](/realtime/react-hooks/subscribe#using-metadata) to subscribe to metadata updates and update your UI in real-time.
+2. Using our [backend functions](/realtime/backend) to subscribe to metadata updates in your backend.
## Limits
The Realtime API in the Trigger.dev Cloud limits the number of concurrent subscriptions, depending on your plan. If you exceed the limit, you will receive an error when trying to subscribe to a run. For more information, see our [pricing page](https://trigger.dev/pricing).
-## Known issues
+## Learn more
-There is currently a known issue where the realtime API does not work if subscribing to a run that has a large payload or large output and are stored in object store instead of the database. We are working on a fix for this issue: https://github.com/triggerdotdev/trigger.dev/issues/1451. As a workaround you'll need to keep payloads and outputs below 128KB when using the realtime API.
+- Read our Realtime blog post ["How we built a real-time service that handles 20,000 updates per second](https://trigger.dev/blog/how-we-built-realtime)
+- Using Realtime: [React Hooks (frontend)](/realtime/react-hooks)
+- Using [Backend (server-side)](/realtime/backend)
From f8f21eae6669b4e46c28186ed04930e722f87b20 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:09:01 +0100
Subject: [PATCH 13/27] Updated auth
---
docs/realtime/auth.mdx | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/docs/realtime/auth.mdx b/docs/realtime/auth.mdx
index 6698cc06e1..e574d07e6b 100644
--- a/docs/realtime/auth.mdx
+++ b/docs/realtime/auth.mdx
@@ -10,18 +10,19 @@ To use the Realtime API, you need to authenticate your requests with Public Acce
There are two types of tokens you can use with the Realtime API:
-- **[Public Access Tokens](#public-access-tokens-for-subscribing-to-runs)** - Used to read and subscribe to run data. Can be used in both frontend and backend applications.
-- **[Trigger Tokens](#trigger-tokens-for-frontend-triggering-only)** - Used to trigger tasks from your frontend. These are more secure, single-use tokens that can only be used in frontend applications.
+- **[Public Access Tokens](#public-access-tokens-for-subscribing-to-runs)** - Used to read and subscribe to run data. Can be used in both the frontend and backend.
+- **[Trigger Tokens](#trigger-tokens-for-frontend-triggering-only)** - Used to trigger tasks from your frontend. These are more secure, single-use tokens that can only be used in the frontend.
## Public Access Tokens (for subscribing to runs)
-Public Access Tokens are used to read and subscribe to run data. They can be used in both frontend and backend applications to subscribe to runs.
+Use Public Access Tokens to subscribe to runs and receive real-time updates in your frontend or backend.
### Creating Public Access Tokens
You can create a Public Access Token using the `auth.createPublicToken` function in your **backend** code:
```tsx
+// Somewhere in your backend code
import { auth } from "@trigger.dev/sdk/v3";
const publicToken = await auth.createPublicToken(); // π this public access token has no permissions, so is pretty useless!
@@ -144,7 +145,7 @@ See our [triggering documentation](/triggering) for detailed examples of how to
Once you have a Public Access Token, you can use it to authenticate requests to the Realtime API in both backend and frontend applications.
-**Backend usage:** See our [backend subscription documentation](/realtime/backend/subscribe) for examples of using tokens with backend functions.
+**Backend usage:** See our [backend documentation](/realtime/backend) for examples of what you can do with Realtime in your backend once you have authenticated with a token.
**Frontend usage:** See our [React hooks documentation](/realtime/react-hooks) for examples of using tokens with frontend components.
@@ -198,8 +199,6 @@ const triggerToken = await auth.createTriggerPublicToken("my-task", {
});
```
-### Triggering tasks from frontend with Trigger Tokens
-
-To trigger tasks from your frontend, you need to use special Trigger Tokens created in your backend. See our [React hooks triggering documentation](/realtime/react-hooks/triggering) for complete examples.
+### Triggering tasks from the frontend with Trigger Tokens
-See our [React hooks documentation](/realtime/react-hooks) for more details on using hooks in your frontend application.
+Check out our [React hooks documentation](/realtime/react-hooks) for examples of how to use Trigger Tokens in your frontend applications.
From e7b0eaa8a30f76ed3d1c0679dad644aaaf2d35c6 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:09:14 +0100
Subject: [PATCH 14/27] Added type safety to the run object page
---
docs/realtime/run-object.mdx | 52 +++++++++++++++++++++++++++++-------
1 file changed, 42 insertions(+), 10 deletions(-)
diff --git a/docs/realtime/run-object.mdx b/docs/realtime/run-object.mdx
index 097bf93400..e5a7b654d7 100644
--- a/docs/realtime/run-object.mdx
+++ b/docs/realtime/run-object.mdx
@@ -4,9 +4,13 @@ sidebarTitle: "The run object"
description: "The run object schema for Realtime subscriptions"
---
-This is the run object returned by Realtime subscriptions (e.g., `runs.subscribeToRun()`).
+The [run object](/realtime/run-object#the-run-object) is the main object returned by Realtime subscriptions (e.g., `runs.subscribeToRun()`). It contains all the information about the run, including the run ID, task identifier, payload, output, and more.
-## Properties
+Type-safety is supported for the run object, so you can infer the types of the run's payload and output. See [type-safety](#type-safety) for more information.
+
+## The run object
+
+### Properties
The run ID.
@@ -117,20 +121,48 @@ This is the run object returned by Realtime subscriptions (e.g., `runs.subscribe
Indicates whether this is a test run.
-## Type safety
+## Type-safety
-You can get type safety for the run's payload and output by passing your task type to subscription functions:
+You can infer the types of the run's payload and output by passing the type of the task to the `subscribeToRun` function. This will give you type-safe access to the run's payload and output.
```ts
-import { runs } from "@trigger.dev/sdk/v3";
+import { runs, tasks } from "@trigger.dev/sdk/v3";
import type { myTask } from "./trigger/my-task";
-for await (const run of runs.subscribeToRun(runId)) {
- // run.payload and run.output are now typed based on your task
- console.log(run.payload.someProperty); // Type-safe
+// Somewhere in your backend code
+async function myBackend() {
+ const handle = await tasks.trigger("my-task", { some: "data" });
- if (run.output) {
- console.log(run.output.result); // Type-safe
+ for await (const run of runs.subscribeToRun(handle.id)) {
+ // This will log the run every time it changes
+ console.log(run.payload.some);
+
+ if (run.output) {
+ // This will log the output if it exists
+ console.log(run.output.some);
+ }
+ }
+}
+```
+
+When using `subscribeToRunsWithTag`, you can pass a union of task types for all the possible tasks that can have the tag.
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { myTask, myOtherTask } from "./trigger/my-task";
+
+// Somewhere in your backend code
+for await (const run of runs.subscribeToRunsWithTag("my-tag")) {
+ // You can narrow down the type based on the taskIdentifier
+ switch (run.taskIdentifier) {
+ case "my-task": {
+ console.log("Run output:", run.output.foo); // This will be type-safe
+ break;
+ }
+ case "my-other-task": {
+ console.log("Run output:", run.output.bar); // This will be type-safe
+ break;
+ }
}
}
```
From e210535be33a348d2b97615fdff44688a8d25ae1 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:09:27 +0100
Subject: [PATCH 15/27] made the subscribe description clearer
---
docs/realtime/react-hooks/subscribe.mdx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/realtime/react-hooks/subscribe.mdx b/docs/realtime/react-hooks/subscribe.mdx
index eaead73567..a137599fd3 100644
--- a/docs/realtime/react-hooks/subscribe.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -206,8 +206,8 @@ See our [Realtime documentation](/realtime) for more information.
All realtime hooks automatically include metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
- To learn how to update metadata from your tasks, see our [backend metadata
- documentation](/realtime/backend/metadata).
+ To learn how to write tasks that use metadata, see our [writing tasks using
+ metadata](/runs/metadata) guide.
### Progress monitoring
From d89e9b8e55f7ad4946a2d9a7b45420fbe780b87e Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:15:35 +0100
Subject: [PATCH 16/27] Fixed links in triggering
---
docs/realtime/react-hooks/triggering.mdx | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/docs/realtime/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
index f1349780c7..c79a668136 100644
--- a/docs/realtime/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -11,12 +11,18 @@ We provide a set of hooks that can be used to trigger tasks from your frontend a
For triggering tasks from your frontend, you need to use βtriggerβ tokens. These can only be used
once to trigger a task and are more secure than regular Public Access Tokens. To learn more about
- how to create and use these tokens, see our [Trigger Tokens](/realtime/auth#trigger-tokens)
- documentation.
+ how to create and use these tokens, see our [Trigger
+ Tokens](/realtime/auth#trigger-tokens-for-frontend-triggering-only) documentation.
## Hooks
+We provide three hooks for triggering tasks from your frontend application:
+
+- `useTaskTrigger` - Trigger a task from your frontend application.
+- `useRealtimeTaskTrigger` - Trigger a task from your frontend application and subscribe to the run.
+- `useRealtimeTaskTriggerWithStreams` - Trigger a task from your frontend application and subscribe to the run, and also receive any streams that are emitted by the task.
+
### useTaskTrigger
The `useTaskTrigger` hook allows you to trigger a task from your frontend application.
@@ -26,7 +32,7 @@ The `useTaskTrigger` hook allows you to trigger a task from your frontend applic
import { useTaskTrigger } from "@trigger.dev/react-hooks";
import type { myTask } from "@/trigger/myTask";
-// π This is the type of your task
+// π This is the type of your task, include this to get type-safety
export function MyComponent({ publicAccessToken }: { publicAccessToken: string }) {
// pass the type of your task here π
@@ -65,7 +71,7 @@ submit({ foo: "bar" }, { tags: ["tag1", "tag2"] });
#### Using the handle object
-You can use the `handle` object to initiate a subsequent [realtime hook](/realtime/react-hooks/realtime#userealtimerun) to subscribe to the run.
+You can use the `handle` object to initiate a subsequent [realtime hook](/realtime/react-hooks/subscribe#userealtimerun) to subscribe to the run.
```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks
From 8a89eefca0d8b54c70d69262cdb0d2f27ee50e32 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:15:39 +0100
Subject: [PATCH 17/27] Fixed link
---
docs/realtime/react-hooks/overview.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index cb31a0079e..9d08ca0493 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -58,7 +58,7 @@ Learn more about [generating and managing tokens in our authentication guide](/r
We provide several categories of hooks:
- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
-- **[Realtime hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, metadata, and more using real-time updates
+- **[Subscribe hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, metadata, and more
- **[Streams hooks](/realtime/react-hooks/streams)** - Subscribe to real-time streams from your tasks
- **[SWR hooks](/realtime/react-hooks/swr)** - Fetch data once and cache it using SWR
From 663613eb63c0b37653eafe798457c7f568d224d4 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:24:27 +0100
Subject: [PATCH 18/27] Removed examples footers
---
docs/realtime/backend/metadata.mdx | 10 +++++++---
docs/realtime/react-hooks/streams.mdx | 4 ----
docs/realtime/react-hooks/subscribe.mdx | 19 ++++++++++---------
docs/realtime/react-hooks/triggering.mdx | 4 ----
4 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/docs/realtime/backend/metadata.mdx b/docs/realtime/backend/metadata.mdx
index ab2b650049..7acfd1ace3 100644
--- a/docs/realtime/backend/metadata.mdx
+++ b/docs/realtime/backend/metadata.mdx
@@ -27,7 +27,9 @@ This makes metadata perfect for:
## Updating metadata from tasks
-Use the metadata API within your task to update metadata in real-time:
+Use the metadata API within your task to update metadata in real-time. In this basic example task, we're updating the progress of a task as it processes items:
+
+### Example task
```ts
import { task, metadata } from "@trigger.dev/sdk/v3";
@@ -61,9 +63,9 @@ async function processItem(item: string) {
}
```
-## Subscribing to metadata updates
+### Subscribing to metadata updates
-Subscribe to runs and receive real-time metadata updates:
+We can now subscribe to the runs and receive real-time metadata updates.
```ts
import { runs } from "@trigger.dev/sdk/v3";
@@ -93,6 +95,8 @@ async function monitorProgress(runId: string) {
}
```
+For more information on how to write tasks that use the metadata API, see our [run metadata docs](/runs/metadata).
+
## Common metadata patterns
### Progress tracking
diff --git a/docs/realtime/react-hooks/streams.mdx b/docs/realtime/react-hooks/streams.mdx
index 161b898f27..d6289ae17f 100644
--- a/docs/realtime/react-hooks/streams.mdx
+++ b/docs/realtime/react-hooks/streams.mdx
@@ -4,8 +4,6 @@ sidebarTitle: Streams
description: Subscribe to real-time streams from your tasks in React components
---
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
These hooks allow you to consume real-time streams from your tasks. Streams are useful for displaying AI/LLM outputs as they're generated, or any other real-time data from your tasks.
@@ -221,5 +219,3 @@ export function MyComponent({
```
All other options (accessToken, baseURL, enabled, id) work the same as the other realtime hooks. See our [realtime hooks documentation](/realtime/react-hooks/realtime#common-options) for more details.
-
-{" "}
diff --git a/docs/realtime/react-hooks/subscribe.mdx b/docs/realtime/react-hooks/subscribe.mdx
index a137599fd3..cce42ec056 100644
--- a/docs/realtime/react-hooks/subscribe.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -4,12 +4,7 @@ sidebarTitle: Subscribe
description: Get live updates from runs, batches, metadata, and more in your frontend application.
---
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
-These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). They automatically include real-time updates for run status, metadata, output, and other properties. Before reading this guide:
-
-- Read our [Realtime documentation](/realtime) to understand how the Trigger.dev realtime API works.
-- Read how to [setup and authenticate](/realtime/react-hooks) using the `@trigger.dev/react-hooks` package.
+These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). They automatically include real-time updates for run status, metadata, output, and other properties.
## Hooks
@@ -206,12 +201,14 @@ See our [Realtime documentation](/realtime) for more information.
All realtime hooks automatically include metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
- To learn how to write tasks that use metadata, see our [writing tasks using
+ To learn how to write tasks with metadata updates, see our [writing tasks using
metadata](/runs/metadata) guide.
### Progress monitoring
+This example demonstrates how to create a progress monitor component that can be used to display the progress of a run:
+
```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks
@@ -272,6 +269,8 @@ export function ProgressMonitor({
### Reusable progress bar
+This example demonstrates how to create a reusable progress bar component that can be used to display the percentage progress of a run:
+
```tsx
"use client";
@@ -333,6 +332,8 @@ export function ProgressBar({ runId, publicAccessToken, title }: ProgressBarProp
### Status indicator with logs
+This example demonstrates how to create a status indicator component that can be used to display the status of a run, and also logs that are emitted by the task:
+
```tsx
"use client";
@@ -392,6 +393,8 @@ export function StatusIndicator({ runId, publicAccessToken }: StatusIndicatorPro
### Multi-stage deployment monitor
+This example demonstrates how to create a multi-stage deployment monitor component that can be used to display the progress of a deployment:
+
```tsx
"use client";
@@ -626,5 +629,3 @@ export function MyComponent({
```
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).
-
-{" "}
diff --git a/docs/realtime/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
index c79a668136..3e94cb941c 100644
--- a/docs/realtime/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -4,8 +4,6 @@ sidebarTitle: Triggering
description: Triggering tasks from your frontend application.
---
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
We provide a set of hooks that can be used to trigger tasks from your frontend application.
@@ -194,5 +192,3 @@ export function MyComponent({ publicAccessToken }: { publicAccessToken: string }
);
}
```
-
-{" "}
From 3412fb3586fc10315df29bc482197bce4a89667e Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 16:56:45 +0100
Subject: [PATCH 19/27] Copy tweak
---
docs/realtime/react-hooks/streams.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/realtime/react-hooks/streams.mdx b/docs/realtime/react-hooks/streams.mdx
index d6289ae17f..c09dba9faf 100644
--- a/docs/realtime/react-hooks/streams.mdx
+++ b/docs/realtime/react-hooks/streams.mdx
@@ -46,7 +46,7 @@ export function MyComponent({
}
```
-You can provide the type of the streams to the `useRealtimeRunWithStreams` hook:
+You can also provide the type of the streams to the `useRealtimeRunWithStreams` hook to get type-safety:
```tsx
import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
From f5da2f5431181138a54278fb2b7bba88f701e7de Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Thu, 31 Jul 2025 17:09:35 +0100
Subject: [PATCH 20/27] Consolidated metadata and subscribe pages
---
docs/docs.json | 1 -
docs/realtime/backend/metadata.mdx | 226 ----------------------------
docs/realtime/backend/overview.mdx | 4 +-
docs/realtime/backend/subscribe.mdx | 217 ++++++++++++++++++++++++++
4 files changed, 218 insertions(+), 230 deletions(-)
delete mode 100644 docs/realtime/backend/metadata.mdx
diff --git a/docs/docs.json b/docs/docs.json
index ffc384eb09..259339b843 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -133,7 +133,6 @@
"pages": [
"realtime/backend/overview",
"realtime/backend/subscribe",
- "realtime/backend/metadata",
"realtime/backend/streams"
]
}
diff --git a/docs/realtime/backend/metadata.mdx b/docs/realtime/backend/metadata.mdx
deleted file mode 100644
index 7acfd1ace3..0000000000
--- a/docs/realtime/backend/metadata.mdx
+++ /dev/null
@@ -1,226 +0,0 @@
----
-title: Metadata
-sidebarTitle: Metadata
-description: Update and subscribe to run metadata in real-time from your backend
----
-
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
-The metadata API allows you to update custom metadata on runs and receive real-time updates when metadata changes. This is useful for tracking progress, storing intermediate results, or adding custom status information that can be monitored in real-time.
-
-
- For frontend applications using React, see our [React hooks metadata
- documentation](/realtime/react-hooks/realtime#using-metadata) for consuming metadata updates in
- your UI.
-
-
-## How metadata works with realtime
-
-When you update metadata from within a task using `metadata.set()`, `metadata.append()`, or other metadata methods, all subscribers to that run will automatically receive the updated run object containing the new metadata.
-
-This makes metadata perfect for:
-
-- Progress tracking
-- Status updates
-- Intermediate results
-- Custom notifications
-
-## Updating metadata from tasks
-
-Use the metadata API within your task to update metadata in real-time. In this basic example task, we're updating the progress of a task as it processes items:
-
-### Example task
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const progressTask = task({
- id: "progress-task",
- run: async (payload: { items: string[] }) => {
- const total = payload.items.length;
-
- for (let i = 0; i < payload.items.length; i++) {
- // Update progress metadata
- metadata.set("progress", {
- current: i + 1,
- total: total,
- percentage: Math.round(((i + 1) / total) * 100),
- currentItem: payload.items[i],
- });
-
- // Process the item
- await processItem(payload.items[i]);
- }
-
- metadata.set("status", "completed");
- return { processed: total };
- },
-});
-
-async function processItem(item: string) {
- // Simulate work
- await new Promise((resolve) => setTimeout(resolve, 1000));
-}
-```
-
-### Subscribing to metadata updates
-
-We can now subscribe to the runs and receive real-time metadata updates.
-
-```ts
-import { runs } from "@trigger.dev/sdk/v3";
-import type { progressTask } from "./trigger/progress-task";
-
-async function monitorProgress(runId: string) {
- for await (const run of runs.subscribeToRun(runId)) {
- console.log(`Run ${run.id} status: ${run.status}`);
-
- if (run.metadata?.progress) {
- const progress = run.metadata.progress as {
- current: number;
- total: number;
- percentage: number;
- currentItem: string;
- };
-
- console.log(`Progress: ${progress.current}/${progress.total} (${progress.percentage}%)`);
- console.log(`Processing: ${progress.currentItem}`);
- }
-
- if (run.metadata?.status === "completed") {
- console.log("Task completed!");
- break;
- }
- }
-}
-```
-
-For more information on how to write tasks that use the metadata API, see our [run metadata docs](/runs/metadata).
-
-## Common metadata patterns
-
-### Progress tracking
-
-Track progress with percentage and current step:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const batchProcessingTask = task({
- id: "batch-processing",
- run: async (payload: { records: any[] }) => {
- for (let i = 0; i < payload.records.length; i++) {
- const record = payload.records[i];
-
- // Update progress
- metadata.set("progress", {
- step: i + 1,
- total: payload.records.length,
- percentage: Math.round(((i + 1) / payload.records.length) * 100),
- currentRecord: record.id,
- });
-
- await processRecord(record);
- }
- },
-});
-```
-
-### Status updates with logs
-
-Append log entries while maintaining status:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const deploymentTask = task({
- id: "deployment",
- run: async (payload: { version: string }) => {
- metadata.set("status", "initializing");
- metadata.append("logs", "Starting deployment...");
-
- // Step 1
- metadata.set("status", "building");
- metadata.append("logs", "Building application...");
- await buildApplication();
-
- // Step 2
- metadata.set("status", "deploying");
- metadata.append("logs", "Deploying to production...");
- await deployToProduction();
-
- // Step 3
- metadata.set("status", "verifying");
- metadata.append("logs", "Running health checks...");
- await runHealthChecks();
-
- metadata.set("status", "completed");
- metadata.append("logs", "Deployment successful!");
- },
-});
-```
-
-### User context and notifications
-
-Store user information and notification preferences:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const userTask = task({
- id: "user-task",
- run: async (payload: { userId: string; action: string }) => {
- // Set user context in metadata
- metadata.set("user", {
- id: payload.userId,
- action: payload.action,
- startedAt: new Date().toISOString(),
- });
-
- // Update status for user notifications
- metadata.set("notification", {
- type: "info",
- message: `Starting ${payload.action} for user ${payload.userId}`,
- });
-
- await performUserAction(payload);
-
- metadata.set("notification", {
- type: "success",
- message: `${payload.action} completed successfully`,
- });
- },
-});
-```
-
-## Type safety
-
-You can get type safety for your metadata by defining types:
-
-```ts
-import { runs } from "@trigger.dev/sdk/v3";
-import type { progressTask } from "./trigger/progress-task";
-
-interface ProgressMetadata {
- progress?: {
- current: number;
- total: number;
- percentage: number;
- currentItem: string;
- };
- status?: "running" | "completed" | "failed";
-}
-
-async function monitorTypedProgress(runId: string) {
- for await (const run of runs.subscribeToRun(runId)) {
- const metadata = run.metadata as ProgressMetadata;
-
- if (metadata?.progress) {
- // Now you have full type safety
- console.log(`Progress: ${metadata.progress.percentage}%`);
- }
- }
-}
-```
-
-{" "}
diff --git a/docs/realtime/backend/overview.mdx b/docs/realtime/backend/overview.mdx
index 9b11275122..853419fe58 100644
--- a/docs/realtime/backend/overview.mdx
+++ b/docs/realtime/backend/overview.mdx
@@ -10,7 +10,7 @@ Use these backend functions to subscribe to runs and streams from your server-si
## Overview
-The backend API provides three main categories of functionality:
+There are three main categories of functionality:
- **[Subscribe functions](/realtime/backend/subscribe)** - Subscribe to run updates using async iterators
- **[Metadata](/realtime/backend/metadata)** - Update and subscribe to run metadata in real-time
@@ -40,5 +40,3 @@ for await (const run of runs.subscribeToRun(handle.id)) {
console.log(`Run ${run.id} status: ${run.status}`);
}
```
-
-{" "}
diff --git a/docs/realtime/backend/subscribe.mdx b/docs/realtime/backend/subscribe.mdx
index 70d39b6578..497680e72d 100644
--- a/docs/realtime/backend/subscribe.mdx
+++ b/docs/realtime/backend/subscribe.mdx
@@ -102,3 +102,220 @@ for await (const run of runs.subscribeToRunsWithTag
+ For frontend applications using React, see our [React hooks metadata
+ documentation](/realtime/react-hooks/realtime#using-metadata) for consuming metadata updates in
+ your UI.
+
+
+When you update metadata from within a task using `metadata.set()`, `metadata.append()`, or other metadata methods, all subscribers to that run will automatically receive the updated run object containing the new metadata.
+
+This makes metadata perfect for:
+
+- Progress tracking
+- Status updates
+- Intermediate results
+- Custom notifications
+
+Use the metadata API within your task to update metadata in real-time. In this basic example task, we're updating the progress of a task as it processes items.
+
+### How to subscribe to metadata updates
+
+This example task updates the progress of a task as it processes items.
+
+```ts
+// Your task code
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const progressTask = task({
+ id: "progress-task",
+ run: async (payload: { items: string[] }) => {
+ const total = payload.items.length;
+
+ for (let i = 0; i < payload.items.length; i++) {
+ // Update progress metadata
+ metadata.set("progress", {
+ current: i + 1,
+ total: total,
+ percentage: Math.round(((i + 1) / total) * 100),
+ currentItem: payload.items[i],
+ });
+
+ // Process the item
+ await processItem(payload.items[i]);
+ }
+
+ metadata.set("status", "completed");
+ return { processed: total };
+ },
+});
+
+async function processItem(item: string) {
+ // Simulate work
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+}
+```
+
+We can now subscribe to the runs and receive real-time metadata updates.
+
+```ts
+// Somewhere in your backend code
+import { runs } from "@trigger.dev/sdk/v3";
+import type { progressTask } from "./trigger/progress-task";
+
+async function monitorProgress(runId: string) {
+ for await (const run of runs.subscribeToRun(runId)) {
+ console.log(`Run ${run.id} status: ${run.status}`);
+
+ if (run.metadata?.progress) {
+ const progress = run.metadata.progress as {
+ current: number;
+ total: number;
+ percentage: number;
+ currentItem: string;
+ };
+
+ console.log(`Progress: ${progress.current}/${progress.total} (${progress.percentage}%)`);
+ console.log(`Processing: ${progress.currentItem}`);
+ }
+
+ if (run.metadata?.status === "completed") {
+ console.log("Task completed!");
+ break;
+ }
+ }
+}
+```
+
+For more information on how to write tasks that use the metadata API, see our [run metadata docs](/runs/metadata).
+
+### Type safety
+
+You can get type safety for your metadata by defining types:
+
+```ts
+import { runs } from "@trigger.dev/sdk/v3";
+import type { progressTask } from "./trigger/progress-task";
+
+interface ProgressMetadata {
+ progress?: {
+ current: number;
+ total: number;
+ percentage: number;
+ currentItem: string;
+ };
+ status?: "running" | "completed" | "failed";
+}
+
+async function monitorTypedProgress(runId: string) {
+ for await (const run of runs.subscribeToRun(runId)) {
+ const metadata = run.metadata as ProgressMetadata;
+
+ if (metadata?.progress) {
+ // Now you have full type safety
+ console.log(`Progress: ${metadata.progress.percentage}%`);
+ }
+ }
+}
+```
+
+### Common metadata patterns
+
+#### Progress tracking
+
+Track progress with percentage and current step:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const batchProcessingTask = task({
+ id: "batch-processing",
+ run: async (payload: { records: any[] }) => {
+ for (let i = 0; i < payload.records.length; i++) {
+ const record = payload.records[i];
+
+ // Update progress
+ metadata.set("progress", {
+ step: i + 1,
+ total: payload.records.length,
+ percentage: Math.round(((i + 1) / payload.records.length) * 100),
+ currentRecord: record.id,
+ });
+
+ await processRecord(record);
+ }
+ },
+});
+```
+
+#### Status updates with logs
+
+Append log entries while maintaining status:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const deploymentTask = task({
+ id: "deployment",
+ run: async (payload: { version: string }) => {
+ metadata.set("status", "initializing");
+ metadata.append("logs", "Starting deployment...");
+
+ // Step 1
+ metadata.set("status", "building");
+ metadata.append("logs", "Building application...");
+ await buildApplication();
+
+ // Step 2
+ metadata.set("status", "deploying");
+ metadata.append("logs", "Deploying to production...");
+ await deployToProduction();
+
+ // Step 3
+ metadata.set("status", "verifying");
+ metadata.append("logs", "Running health checks...");
+ await runHealthChecks();
+
+ metadata.set("status", "completed");
+ metadata.append("logs", "Deployment successful!");
+ },
+});
+```
+
+#### User context and notifications
+
+Store user information and notification preferences:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const userTask = task({
+ id: "user-task",
+ run: async (payload: { userId: string; action: string }) => {
+ // Set user context in metadata
+ metadata.set("user", {
+ id: payload.userId,
+ action: payload.action,
+ startedAt: new Date().toISOString(),
+ });
+
+ // Update status for user notifications
+ metadata.set("notification", {
+ type: "info",
+ message: `Starting ${payload.action} for user ${payload.userId}`,
+ });
+
+ await performUserAction(payload);
+
+ metadata.set("notification", {
+ type: "success",
+ message: `${payload.action} completed successfully`,
+ });
+ },
+});
+```
From f807f1a872852eae45aa86fba0af5e775d84ae9c Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 1 Aug 2025 11:50:05 +0100
Subject: [PATCH 21/27] moved metadata task examples to metadata
---
docs/realtime/backend/subscribe.mdx | 98 +------------------------
docs/realtime/overview.mdx | 10 +--
docs/realtime/react-hooks/subscribe.mdx | 7 +-
docs/runs/metadata.mdx | 98 +++++++++++++++++++++++++
4 files changed, 106 insertions(+), 107 deletions(-)
diff --git a/docs/realtime/backend/subscribe.mdx b/docs/realtime/backend/subscribe.mdx
index 497680e72d..4bdd2fd53d 100644
--- a/docs/realtime/backend/subscribe.mdx
+++ b/docs/realtime/backend/subscribe.mdx
@@ -192,7 +192,7 @@ async function monitorProgress(runId: string) {
}
```
-For more information on how to write tasks that use the metadata API, see our [run metadata docs](/runs/metadata).
+For more information on how to write tasks that use the metadata API, as well as more examples, see our [run metadata docs](/runs/metadata#more-metadata-task-examples).
### Type safety
@@ -223,99 +223,3 @@ async function monitorTypedProgress(runId: string) {
}
}
```
-
-### Common metadata patterns
-
-#### Progress tracking
-
-Track progress with percentage and current step:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const batchProcessingTask = task({
- id: "batch-processing",
- run: async (payload: { records: any[] }) => {
- for (let i = 0; i < payload.records.length; i++) {
- const record = payload.records[i];
-
- // Update progress
- metadata.set("progress", {
- step: i + 1,
- total: payload.records.length,
- percentage: Math.round(((i + 1) / payload.records.length) * 100),
- currentRecord: record.id,
- });
-
- await processRecord(record);
- }
- },
-});
-```
-
-#### Status updates with logs
-
-Append log entries while maintaining status:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const deploymentTask = task({
- id: "deployment",
- run: async (payload: { version: string }) => {
- metadata.set("status", "initializing");
- metadata.append("logs", "Starting deployment...");
-
- // Step 1
- metadata.set("status", "building");
- metadata.append("logs", "Building application...");
- await buildApplication();
-
- // Step 2
- metadata.set("status", "deploying");
- metadata.append("logs", "Deploying to production...");
- await deployToProduction();
-
- // Step 3
- metadata.set("status", "verifying");
- metadata.append("logs", "Running health checks...");
- await runHealthChecks();
-
- metadata.set("status", "completed");
- metadata.append("logs", "Deployment successful!");
- },
-});
-```
-
-#### User context and notifications
-
-Store user information and notification preferences:
-
-```ts
-import { task, metadata } from "@trigger.dev/sdk/v3";
-
-export const userTask = task({
- id: "user-task",
- run: async (payload: { userId: string; action: string }) => {
- // Set user context in metadata
- metadata.set("user", {
- id: payload.userId,
- action: payload.action,
- startedAt: new Date().toISOString(),
- });
-
- // Update status for user notifications
- metadata.set("notification", {
- type: "info",
- message: `Starting ${payload.action} for user ${payload.userId}`,
- });
-
- await performUserAction(payload);
-
- metadata.set("notification", {
- type: "success",
- message: `${payload.action} completed successfully`,
- });
- },
-});
-```
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index a2aa9b0ad1..3e50fb9777 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -8,13 +8,9 @@ import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time updates for runs. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
-## Authentication
-
-All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
-
## What you can do with Realtime
-You can subscribe to real-time updates for different scopes of runs:
+Subscribe to real-time updates for different scopes of runs:
- **Specific runs** - Monitor individual run progress by run ID
- **Runs with specific tags** - Track all runs that have certain [tags](/tags) (e.g., all runs tagged with `user:123`)
@@ -28,6 +24,10 @@ Once subscribed, you'll receive the complete [run object](/realtime/run-object)
- **Tag changes** - When [tags](/tags) are added or removed from the run
- **Stream data** - Real-time data chunks from your tasks, perfect for AI/LLM streaming ([React hooks](/realtime/react-hooks/streams) | [backend](/realtime/backend/streams))
+## Authentication
+
+All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
+
## Realtime approaches
### Frontend implementation
diff --git a/docs/realtime/react-hooks/subscribe.mdx b/docs/realtime/react-hooks/subscribe.mdx
index cce42ec056..d777d00135 100644
--- a/docs/realtime/react-hooks/subscribe.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -196,14 +196,11 @@ export function MyComponent({ batchId }: { batchId: string }) {
See our [Realtime documentation](/realtime) for more information.
-## Using Metadata
+## Using metadata to show progress in your UI
All realtime hooks automatically include metadata updates. Whenever your task updates metadata using `metadata.set()`, `metadata.append()`, or other metadata methods, your component will re-render with the updated data.
-
- To learn how to write tasks with metadata updates, see our [writing tasks using
- metadata](/runs/metadata) guide.
-
+To learn how to write tasks using metadata, see our [metadata](/runs/metadata) guide.
### Progress monitoring
diff --git a/docs/runs/metadata.mdx b/docs/runs/metadata.mdx
index e6b2caf0b9..853e3aae97 100644
--- a/docs/runs/metadata.mdx
+++ b/docs/runs/metadata.mdx
@@ -514,6 +514,104 @@ Combined with [Realtime](/realtime), you could use this to show a live progress
height="100%"
/>
+## More metadata task examples
+
+Using metadata updates in conjunction with our [Realtime React hooks](/realtime/react-hooks/overview) can be a powerful way to build real-time UIs. Here are some example tasks demonstrating how to use metadata in your tasks to track progress, status, and more:
+
+### Progress tracking
+
+Track progress with percentage and current step:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const batchProcessingTask = task({
+ id: "batch-processing",
+ run: async (payload: { records: any[] }) => {
+ for (let i = 0; i < payload.records.length; i++) {
+ const record = payload.records[i];
+
+ // Update progress
+ metadata.set("progress", {
+ step: i + 1,
+ total: payload.records.length,
+ percentage: Math.round(((i + 1) / payload.records.length) * 100),
+ currentRecord: record.id,
+ });
+
+ await processRecord(record);
+ }
+ },
+});
+```
+
+### Status updates with logs
+
+Append log entries while maintaining status:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const deploymentTask = task({
+ id: "deployment",
+ run: async (payload: { version: string }) => {
+ metadata.set("status", "initializing");
+ metadata.append("logs", "Starting deployment...");
+
+ // Step 1
+ metadata.set("status", "building");
+ metadata.append("logs", "Building application...");
+ await buildApplication();
+
+ // Step 2
+ metadata.set("status", "deploying");
+ metadata.append("logs", "Deploying to production...");
+ await deployToProduction();
+
+ // Step 3
+ metadata.set("status", "verifying");
+ metadata.append("logs", "Running health checks...");
+ await runHealthChecks();
+
+ metadata.set("status", "completed");
+ metadata.append("logs", "Deployment successful!");
+ },
+});
+```
+
+### User context and notifications
+
+Store user information and notification preferences:
+
+```ts
+import { task, metadata } from "@trigger.dev/sdk/v3";
+
+export const userTask = task({
+ id: "user-task",
+ run: async (payload: { userId: string; action: string }) => {
+ // Set user context in metadata
+ metadata.set("user", {
+ id: payload.userId,
+ action: payload.action,
+ startedAt: new Date().toISOString(),
+ });
+
+ // Update status for user notifications
+ metadata.set("notification", {
+ type: "info",
+ message: `Starting ${payload.action} for user ${payload.userId}`,
+ });
+
+ await performUserAction(payload);
+
+ metadata.set("notification", {
+ type: "success",
+ message: `${payload.action} completed successfully`,
+ });
+ },
+});
+```
+
## Metadata propagation
Metadata is NOT propagated to child tasks. If you want to pass metadata to a child task, you must do so explicitly:
From 129f089061482a3840055077873165cd9246b968 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 1 Aug 2025 12:15:31 +0100
Subject: [PATCH 22/27] Fixed links
---
docs/realtime/backend/overview.mdx | 2 +-
docs/realtime/overview.mdx | 14 ++++++--------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/docs/realtime/backend/overview.mdx b/docs/realtime/backend/overview.mdx
index 853419fe58..079004e923 100644
--- a/docs/realtime/backend/overview.mdx
+++ b/docs/realtime/backend/overview.mdx
@@ -13,7 +13,7 @@ Use these backend functions to subscribe to runs and streams from your server-si
There are three main categories of functionality:
- **[Subscribe functions](/realtime/backend/subscribe)** - Subscribe to run updates using async iterators
-- **[Metadata](/realtime/backend/metadata)** - Update and subscribe to run metadata in real-time
+- **[Metadata](/realtime/backend/subscribe#subscribe-to-metadata-updates-from-your-tasks)** - Update and subscribe to run metadata in real-time
- **[Streams](/realtime/backend/streams)** - Emit and consume real-time streaming data from your tasks
## Authentication
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 3e50fb9777..5ff33d9333 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -8,9 +8,7 @@ import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time updates for runs. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
-## What you can do with Realtime
-
-Subscribe to real-time updates for different scopes of runs:
+You can subscribe to real-time updates for different scopes of runs:
- **Specific runs** - Monitor individual run progress by run ID
- **Runs with specific tags** - Track all runs that have certain [tags](/tags) (e.g., all runs tagged with `user:123`)
@@ -20,21 +18,21 @@ Subscribe to real-time updates for different scopes of runs:
Once subscribed, you'll receive the complete [run object](/realtime/run-object) with automatic real-time updates whenever the [run changes](/realtime/how-it-works#run-changes), including:
- **Status changes** - queued β executing β completed, etc.
-- **Metadata updates** - Custom progress tracking, status updates, user data, etc. ([React hooks](/realtime/react-hooks/subscribe#using-metadata) | [backend](/realtime/backend/metadata))
+- **Metadata updates** - Custom progress tracking, status updates, user data, etc. ([React hooks](/realtime/react-hooks/subscribe#using-metadata-to-show-progress-in-your-ui) | [backend](/realtime/backend/subscribe#subscribe-to-metadata-updates-from-your-tasks))
- **Tag changes** - When [tags](/tags) are added or removed from the run
- **Stream data** - Real-time data chunks from your tasks, perfect for AI/LLM streaming ([React hooks](/realtime/react-hooks/streams) | [backend](/realtime/backend/streams))
-## Authentication
+## Using Realtime in your applications
-All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
+### Authentication
-## Realtime approaches
+All Realtime subscriptions require authentication so you can securely trigger and subscribe to runs. See our [authentication guide](/realtime/auth) for more details.
### Frontend implementation
Use our React hooks to build real-time UIs that update as runs execute. Ideal for progress bars, status indicators, and live dashboards.
-β **[See our React hooks guide](/realtime/react-hooks)**
+β **[See our React hooks guide](/realtime/react-hooks/)**
### Backend implementation
From a8202ed0c686ecac719465ca58ad7fd35e83c601 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 1 Aug 2025 12:30:23 +0100
Subject: [PATCH 23/27] Fixing links like zelda
---
docs/guides/example-projects/batch-llm-evaluator.mdx | 2 +-
.../example-projects/vercel-ai-sdk-image-generator.mdx | 4 ++--
docs/realtime/backend/streams.mdx | 4 ----
docs/realtime/backend/subscribe.mdx | 4 ++--
docs/realtime/react-hooks/overview.mdx | 2 +-
docs/realtime/react-hooks/streams.mdx | 2 +-
docs/realtime/react-hooks/swr.mdx | 6 +++---
7 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/docs/guides/example-projects/batch-llm-evaluator.mdx b/docs/guides/example-projects/batch-llm-evaluator.mdx
index 4457e5fbba..5a04331391 100644
--- a/docs/guides/example-projects/batch-llm-evaluator.mdx
+++ b/docs/guides/example-projects/batch-llm-evaluator.mdx
@@ -39,7 +39,7 @@ This demo is a full stack example that uses the following:
- View the Trigger.dev task code in the [src/trigger/batch.ts](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/trigger/batch.ts) file.
- The `evaluateModels` task uses the `batch.triggerByTaskAndWait` method to distribute the task to the different LLM models.
- It then passes the results through to a `summarizeEvals` task that calculates some dummy "tags" for each LLM response.
-- We use a [useRealtimeRunsWithTag](/realtime/react-hooks/realtime#userealtimerunswithtag) hook to subscribe to the different evaluation tasks runs in the [src/components/llm-evaluator.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/llm-evaluator.tsx) file.
+- We use a [useRealtimeRunsWithTag](/realtime/react-hooks/subscribe#userealtimerunswithtag) hook to subscribe to the different evaluation tasks runs in the [src/components/llm-evaluator.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/llm-evaluator.tsx) file.
- We then pass the relevant run down into three different components for the different models:
- The `AnthropicEval` component: [src/components/evals/Anthropic.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/evals/Anthropic.tsx)
- The `XAIEval` component: [src/components/evals/XAI.tsx](https://github.com/triggerdotdev/examples/blob/main/batch-llm-evaluator/src/components/evals/XAI.tsx)
diff --git a/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx b/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
index a4a1661224..ea13ac92b0 100644
--- a/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
+++ b/docs/guides/example-projects/vercel-ai-sdk-image-generator.mdx
@@ -11,7 +11,7 @@ import RealtimeLearnMore from "/snippets/realtime-learn-more.mdx";
This demo is a full stack example that uses the following:
- A [Next.js](https://nextjs.org/) app using [shadcn](https://ui.shadcn.com/) for the UI
-- Our 'useRealtimeRun' [React hook](/realtime/react-hooks/realtime) to subscribe to the run and show updates on the frontend
+- Our 'useRealtimeRun' [React hook](/realtime/react-hooks/subscribe#userealtimerun) to subscribe to the run and show updates on the frontend
- The [Vercel AI SDK](https://sdk.vercel.ai/docs/introduction) to [generate images](https://sdk.vercel.ai/docs/ai-sdk-core/image-generation) using OpenAI's DALL-E models
## GitHub repo
@@ -36,6 +36,6 @@ This demo is a full stack example that uses the following:
## Relevant code
- View the Trigger.dev task code which generates the image using the Vercel AI SDK in [src/trigger/realtime-generate-image.ts](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/trigger/realtime-generate-image.ts).
-- We use a [useRealtimeRun](/realtime/react-hooks/realtime#userealtimerun) hook to subscribe to the run in [src/app/processing/[id]/ProcessingContent.tsx](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/app/processing/[id]/ProcessingContent.tsx).
+- We use a [useRealtimeRun](/realtime/react-hooks/subscribe#userealtimerun) hook to subscribe to the run in [src/app/processing/[id]/ProcessingContent.tsx](https://github.com/triggerdotdev/examples/tree/main/vercel-ai-sdk-image-generator/src/app/processing/[id]/ProcessingContent.tsx).
diff --git a/docs/realtime/backend/streams.mdx b/docs/realtime/backend/streams.mdx
index a291b3ee8b..7a5ae28d51 100644
--- a/docs/realtime/backend/streams.mdx
+++ b/docs/realtime/backend/streams.mdx
@@ -4,8 +4,6 @@ sidebarTitle: Streams
description: Emit and consume real-time streaming data from your tasks
---
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
The Streams API allows you to stream data from your tasks to the outside world in realtime using the [metadata](/runs/metadata) system. This is particularly useful for streaming LLM outputs or any other real-time data.
@@ -351,5 +349,3 @@ export const aiStreamingWithTools = schemaTask({
},
});
```
-
-{" "}
diff --git a/docs/realtime/backend/subscribe.mdx b/docs/realtime/backend/subscribe.mdx
index 4bdd2fd53d..973ce1414c 100644
--- a/docs/realtime/backend/subscribe.mdx
+++ b/docs/realtime/backend/subscribe.mdx
@@ -109,8 +109,8 @@ The metadata API allows you to update custom metadata on runs and receive real-t
For frontend applications using React, see our [React hooks metadata
- documentation](/realtime/react-hooks/realtime#using-metadata) for consuming metadata updates in
- your UI.
+ documentation](/realtime/react-hooks/subscribe#using-metadata-to-show-progress-in-your-ui) for
+ consuming metadata updates in your UI.
When you update metadata from within a task using `metadata.set()`, `metadata.append()`, or other metadata methods, all subscribers to that run will automatically receive the updated run object containing the new metadata.
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index 9d08ca0493..1f246e00ab 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -58,7 +58,7 @@ Learn more about [generating and managing tokens in our authentication guide](/r
We provide several categories of hooks:
- **[Triggering hooks](/realtime/react-hooks/triggering)** - Trigger tasks from your frontend application
-- **[Subscribe hooks](/realtime/react-hooks/realtime)** - Subscribe to runs, batches, metadata, and more
+- **[Subscribe hooks](/realtime/react-hooks/subscribe)** - Subscribe to runs, batches, metadata, and more
- **[Streams hooks](/realtime/react-hooks/streams)** - Subscribe to real-time streams from your tasks
- **[SWR hooks](/realtime/react-hooks/swr)** - Fetch data once and cache it using SWR
diff --git a/docs/realtime/react-hooks/streams.mdx b/docs/realtime/react-hooks/streams.mdx
index c09dba9faf..aaf153bf3d 100644
--- a/docs/realtime/react-hooks/streams.mdx
+++ b/docs/realtime/react-hooks/streams.mdx
@@ -218,4 +218,4 @@ export function MyComponent({
}
```
-All other options (accessToken, baseURL, enabled, id) work the same as the other realtime hooks. See our [realtime hooks documentation](/realtime/react-hooks/realtime#common-options) for more details.
+All other options (accessToken, baseURL, enabled, id) work the same as the other realtime hooks.
diff --git a/docs/realtime/react-hooks/swr.mdx b/docs/realtime/react-hooks/swr.mdx
index 6132d3b9c7..6eae5b180f 100644
--- a/docs/realtime/react-hooks/swr.mdx
+++ b/docs/realtime/react-hooks/swr.mdx
@@ -7,9 +7,9 @@ description: Fetch and cache data using SWR-based hooks
SWR hooks use the [swr](https://swr.vercel.app/) library to fetch data once and cache it. These hooks are useful when you need to fetch data without real-time updates.
- While SWR can be configured to poll for updates, we recommend using the [Realtime
- hooks](/realtime/react-hooks/realtime) for most use-cases due to rate-limits and the way the
- Trigger.dev API works.
+ While SWR can be configured to poll for updates, we recommend using our other [Realtime
+ hooks](/realtime/react-hooks/) for most use-cases due to rate-limits and the way the Trigger.dev
+ API works.
## useRun
From 4cc25292ed08c533a5f411d9900060a4149c3ac0 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 1 Aug 2025 12:33:31 +0100
Subject: [PATCH 24/27] Removed dead import
---
docs/realtime/overview.mdx | 2 --
1 file changed, 2 deletions(-)
diff --git a/docs/realtime/overview.mdx b/docs/realtime/overview.mdx
index 5ff33d9333..998a2e6295 100644
--- a/docs/realtime/overview.mdx
+++ b/docs/realtime/overview.mdx
@@ -4,8 +4,6 @@ sidebarTitle: Overview
description: Using the Trigger.dev Realtime API to trigger and/or subscribe to runs in real-time.
---
-import RealtimeExamplesCards from "/snippets/realtime-examples-cards.mdx";
-
Trigger.dev Realtime allows you to trigger, subscribe to, and get real-time updates for runs. This is useful for monitoring runs, updating UIs, and building real-time dashboards.
You can subscribe to real-time updates for different scopes of runs:
From 4921a980ea974234be1bed0ddf053be9573f5514 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Fri, 1 Aug 2025 18:49:56 +0100
Subject: [PATCH 25/27] Clearer titles
---
docs/realtime/react-hooks/subscribe.mdx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/realtime/react-hooks/subscribe.mdx b/docs/realtime/react-hooks/subscribe.mdx
index d777d00135..bab6ab6ee1 100644
--- a/docs/realtime/react-hooks/subscribe.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -10,11 +10,13 @@ These hooks allow you to subscribe to runs, batches, and streams using [Trigger.
## Triggering + Realtime hooks
-For triggering tasks and immediately subscribing to their runs, we provide combo hooks:
+For triggering tasks and immediately subscribing to their runs, we provide combo hooks, details on how to use them can be found in the [triggering](/realtime/react-hooks/triggering) section.
- **[`useRealtimeTaskTrigger`](/realtime/react-hooks/triggering#userealtimetasktrigger)** - Trigger a task and subscribe to the run
- **[`useRealtimeTaskTriggerWithStreams`](/realtime/react-hooks/triggering#userealtimetasktriggerwithstreams)** - Trigger a task and subscribe to both run updates and streams
+## Other Realtime subscription hooks
+
### useRealtimeRun
The `useRealtimeRun` hook allows you to subscribe to a run by its ID.
From 6c4efe6a2107ea04c150dde8fa5a3229f605989f Mon Sep 17 00:00:00 2001
From: James Ritchie
Date: Thu, 7 Aug 2025 15:30:50 +0100
Subject: [PATCH 26/27] Cap R for Realtime
---
docs/realtime/react-hooks/overview.mdx | 2 +-
docs/realtime/react-hooks/subscribe.mdx | 2 +-
docs/realtime/react-hooks/triggering.mdx | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/realtime/react-hooks/overview.mdx b/docs/realtime/react-hooks/overview.mdx
index 1f246e00ab..7cf84c63f0 100644
--- a/docs/realtime/react-hooks/overview.mdx
+++ b/docs/realtime/react-hooks/overview.mdx
@@ -64,7 +64,7 @@ We provide several categories of hooks:
## SWR vs Realtime hooks
-We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](https://swr.vercel.app/) library to fetch data once and cache it. The Realtime hooks use [Trigger.dev realtime](/realtime) to subscribe to updates in real-time.
+We offer two "styles" of hooks: SWR and Realtime. The SWR hooks use the [swr](https://swr.vercel.app/) library to fetch data once and cache it. The Realtime hooks use [Trigger.dev Realtime](/realtime) to subscribe to updates in real-time.
It can be a little confusing which one to use because [swr](https://swr.vercel.app/) can also be
diff --git a/docs/realtime/react-hooks/subscribe.mdx b/docs/realtime/react-hooks/subscribe.mdx
index bab6ab6ee1..4cf0a79da3 100644
--- a/docs/realtime/react-hooks/subscribe.mdx
+++ b/docs/realtime/react-hooks/subscribe.mdx
@@ -4,7 +4,7 @@ sidebarTitle: Subscribe
description: Get live updates from runs, batches, metadata, and more in your frontend application.
---
-These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev realtime](/realtime). They automatically include real-time updates for run status, metadata, output, and other properties.
+These hooks allow you to subscribe to runs, batches, and streams using [Trigger.dev Realtime](/realtime). They automatically include real-time updates for run status, metadata, output, and other properties.
## Hooks
diff --git a/docs/realtime/react-hooks/triggering.mdx b/docs/realtime/react-hooks/triggering.mdx
index 3e94cb941c..50320ccd48 100644
--- a/docs/realtime/react-hooks/triggering.mdx
+++ b/docs/realtime/react-hooks/triggering.mdx
@@ -69,7 +69,7 @@ submit({ foo: "bar" }, { tags: ["tag1", "tag2"] });
#### Using the handle object
-You can use the `handle` object to initiate a subsequent [realtime hook](/realtime/react-hooks/subscribe#userealtimerun) to subscribe to the run.
+You can use the `handle` object to initiate a subsequent [Realtime hook](/realtime/react-hooks/subscribe#userealtimerun) to subscribe to the run.
```tsx
"use client"; // This is needed for Next.js App Router or other RSC frameworks
@@ -135,7 +135,7 @@ export function MyComponent({ publicAccessToken }: { publicAccessToken: string }
return
Error: {error.message}
;
}
- // This is the realtime run object, which will automatically update when the run changes
+ // This is the Realtime run object, which will automatically update when the run changes
if (run) {
return
Run ID: {run.id}
;
}
From 8bd051949451be1faae63b9bb26c3e747e2e68a0 Mon Sep 17 00:00:00 2001
From: James Ritchie
Date: Thu, 7 Aug 2025 15:55:57 +0100
Subject: [PATCH 27/27] Fixes broken link
---
docs/manual-setup.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/manual-setup.mdx b/docs/manual-setup.mdx
index 328877de1b..28bf46c2e3 100644
--- a/docs/manual-setup.mdx
+++ b/docs/manual-setup.mdx
@@ -296,7 +296,7 @@ export function TaskStatus({
}
```
-For more information, see the [React Hooks documentation](/frontend/react-hooks/overview).
+For more information, see the [React Hooks documentation](/realtime/react-hooks/overview).
## Build extensions