SuggestedActions shows prompts the user can send next. It never calls host APIs directly.
import { SuggestedActions } from "@/components/fable-ui/suggested-actions/suggested-actions"
export function FollowUps() {
return (
<SuggestedActions
title="Next safe actions"
description="Prompt-only follow ups for the current answer."
actions={[
{ label: "Compare to yesterday", prompt: "Compare this to yesterday." },
{ label: "Show source rows", prompt: "Show the source rows." },Installation#
pnpm dlx shadcn@latest add shobky/fable-ui/suggested-actionsInstalled files include:
components/fable-ui/suggested-actions/suggested-actions.tsx
components/fable-ui/suggested-actions/index.ts
lib/fable-ui/tools/show-next-actions-tool.ts
lib/fable-ui/manifests/show-next-actions.mdThe component depends on shared Fable core plus shadcn card, button, and badge primitives.
Usage#
Use the component directly when you already own the action list:
import { SuggestedActions } from "@/components/fable-ui/suggested-actions/suggested-actions"
export function FollowUps() {
return (
<SuggestedActions
title="Next safe actions"
description="Prompt-only follow ups for the current answer."
actions={[
{ label: "Compare to yesterday", prompt: "Compare this to yesterday." },
{ label: "Show source rows", prompt: "Show the source rows." },
]}
onAction={(action) => {
console.log(action.prompt)
}}
/>
)
}If no onAction handler is provided, buttons render disabled. This prevents copied components from showing clickable controls that do nothing.
How clicks work#
Clicking a suggested action sends action.prompt as the next user message. The label is display text for the button; the prompt is the model-facing message.
button click
-> SuggestedActions.onAction(action)
-> Fable renderer handlers.onSuggestedAction(action)
-> host chat calls sendMessage({ text: action.prompt })
-> existing chat route receives normal UI messages
-> model decides whether to answer in text or call another Fable toolThe component does not call host APIs, execute writes, or bypass the model. It only gives the user a faster way to send a complete prompt into the same chat flow they already use.
AI SDK chat wiring#
When rendering Fable tool parts, pass an onSuggestedAction handler that reuses your normal sendMessage path:
"use client"
import { useChat } from "@ai-sdk/react"
import { DefaultChatTransport } from "ai"
import { FableToolPart } from "@/lib/fable-ui/core/tool-renderer"
import { showNextActions } from "@/lib/fable-ui/tools/show-next-actions-tool"
const registry = {
show_next_actions: showNextActions,
}
export function ChatToolPart({ part }: { part: unknown }) {
const { sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
})
const isBusy = status === "submitted" || status === "streaming"
return (
<FableToolPart
part={part}
registry={registry}
handlers={{
onSuggestedAction: isBusy
? undefined
: (action) => {
void sendMessage({ text: action.prompt })
},
}}
/>
)
}Most apps already create useChat higher in the chat shell. In that case, pass the handler down through your message and tool-part components instead of creating a second useChat instance.
If your normal composer sends request options, such as provider, model, organization id, or browser-held credentials, use the same options for suggested actions:
await sendMessage(
{ text: action.prompt },
{
body: {
provider,
model,
orgId,
},
},
)Tool#
The AI SDK tool name is show_next_actions.
Use it for prompt-only follow-ups such as "Compare to yesterday" or "Show the source rows". Do not use it to perform writes, deletes, charges, sends, or status changes. For side effects, use a confirmation or form flow where the host app validates and executes the action.
States#
The preview shows ready, loading, empty, error, and disabled states. Disabled suggested actions are visible but cannot be sent until the host app allows interaction.
Manifest#
The manifest is the copyable routing contract for prompt-only next actions. Read the Manifests guide for the shared format.
---
tool: show_next_actions
type: registry:component
---
# show_next_actions
Use `show_next_actions` for safe follow-up prompts the user may choose to send back into the chat.
Each action has UI copy and model-facing intent:
- `label` is the short button text shown to the user.
- `prompt` is the complete user message the host chat sends if the user clicks the button.
- `description` may add brief context under the label.
Prompts must be complete enough to send as the user's next turn without hidden state. Good prompts include the subject and desired operation, such as "Compare this revenue metric to yesterday" or "Show the source rows for this answer."
Do not use this tool to perform host API calls, writes, purchases, deletes, sends, refunds, approvals, or status changes. Suggested actions are prompt-only. Side effects belong in confirmation, form, or host-owned action flows where the app validates and executes the operation.