You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Only one tab can send at a time. Other tabs enter read-only mode with real-time message updates via `BroadcastChannel`. When the active tab's turn completes, any tab can send next. Crashed tabs are detected via heartbeat timeout (10s).
20
+
21
+
See [Multi-tab coordination](/ai-chat/frontend#multi-tab-coordination) and [`useMultiTabChat`](/ai-chat/reference#usemultitabchat).
22
+
23
+
## Error stack truncation
24
+
25
+
Large error stacks no longer OOM the worker process. Stacks are capped at 50 frames (top 5 + bottom 45), individual lines at 1024 chars, messages at 1000 chars. Applied in `parseError`, `sanitizeError`, and OTel span recording.
Copy file name to clipboardExpand all lines: docs/ai-chat/frontend.mdx
+59Lines changed: 59 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -406,6 +406,65 @@ for await (const chunk of stream) {
406
406
}
407
407
```
408
408
409
+
## Multi-tab coordination
410
+
411
+
When the same chat is open in multiple browser tabs, `multiTab: true` prevents duplicate messages and syncs conversation state across tabs. Only one tab can send at a time. Other tabs enter read-only mode with real-time message updates.
This chat is active in another tab. Messages are read-only.
437
+
</div>
438
+
)}
439
+
{/* message list */}
440
+
<input
441
+
disabled={isReadOnly}
442
+
placeholder={isReadOnly?"Active in another tab":"Type a message..."}
443
+
/>
444
+
</div>
445
+
);
446
+
}
447
+
```
448
+
449
+
### How it works
450
+
451
+
1. When a tab sends a message, the transport "claims" the chatId via `BroadcastChannel`
452
+
2. Other tabs detect the claim and enter read-only mode (`isReadOnly: true`)
453
+
3. The active tab broadcasts its messages so read-only tabs see updates in real-time
454
+
4. When the turn completes, the claim is released. Any tab can send next.
455
+
5. Heartbeats detect crashed tabs (10s timeout clears stale claims)
456
+
457
+
### What `useMultiTabChat` does
458
+
459
+
- Returns `{ isReadOnly }` for disabling the input UI
460
+
- Broadcasts `messages` from the active tab to other tabs
461
+
- Calls `setMessages` on read-only tabs when messages arrive from the active tab
462
+
- Tracks read-only state via the transport's `BroadcastChannel` coordinator
463
+
464
+
<Note>
465
+
Multi-tab coordination is same-browser only (`BroadcastChannel` is a browser API). It gracefully degrades to a no-op in Node.js, SSR, or browsers without `BroadcastChannel` support. Cross-device coordination requires server-side involvement.
466
+
</Note>
467
+
409
468
## Self-hosting
410
469
411
470
If you're self-hosting Trigger.dev, pass the `baseURL` option:
Copy file name to clipboardExpand all lines: docs/ai-chat/reference.mdx
+40Lines changed: 40 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -534,6 +534,20 @@ const transport = useTriggerChatTransport({
534
534
});
535
535
```
536
536
537
+
### multiTab
538
+
539
+
Enable multi-tab coordination. When `true`, only one browser tab can send messages to a given chatId at a time. Other tabs enter read-only mode with real-time message updates via `BroadcastChannel`.
540
+
541
+
```ts
542
+
const transport =useTriggerChatTransport({
543
+
task: "my-chat",
544
+
accessToken,
545
+
multiTab: true,
546
+
});
547
+
```
548
+
549
+
No-op when `BroadcastChannel` is unavailable (SSR, Node.js). See [Multi-tab coordination](/ai-chat/frontend#multi-tab-coordination).
550
+
537
551
### triggerOptions
538
552
539
553
Options forwarded to the Trigger.dev API when starting a new run. Only applies to the first message — subsequent messages reuse the same run.
@@ -629,6 +643,32 @@ const transport = useTriggerChatTransport<typeof myChat>({
629
643
630
644
The transport is created once on first render and reused across re-renders. Pass a type parameter for compile-time validation of the task ID.
631
645
646
+
## useMultiTabChat
647
+
648
+
React hook for multi-tab message coordination. Import from `@trigger.dev/sdk/chat/react`.
0 commit comments