component-rendering
SKILL.md
Component Rendering
Handles streaming props and persistent component state.
Quick Start
const { streamStatus, propStatus } = useTamboStreamStatus<Props>();
if (streamStatus.isPending) return <Skeleton />;
if (streamStatus.isStreaming) return <LoadingIndicator />;
Stream Status
Track overall and per-prop streaming status:
import { useTamboStreamStatus } from "@tambo-ai/react";
function MyComponent({ title, items }: Props) {
const { streamStatus, propStatus } = useTamboStreamStatus<Props>();
// Global status
if (streamStatus.isPending) return <Skeleton />;
if (streamStatus.isStreaming) return <LoadingIndicator />;
if (streamStatus.isError) return <Error message={streamStatus.streamError} />;
// Per-prop status
return (
<h2 className={propStatus.title?.isStreaming ? "animate-pulse" : ""}>
{title}
</h2>
);
}
StreamStatus Properties
| Property | Description |
|---|---|
isPending |
No tokens received yet |
isStreaming |
Active streaming in progress |
isSuccess |
All props finished without error |
isError |
Fatal error occurred |
streamError |
Error object if failed |
PropStatus (per-prop)
| Property | Description |
|---|---|
isPending |
No tokens for this prop yet |
isStreaming |
Prop has partial content |
isSuccess |
Prop finished streaming |
error |
Error for this prop (if any) |
Component State
Make state visible to AI and persist across sessions:
import { useTamboComponentState, useTamboStreamStatus } from "@tambo-ai/react";
function EditableCard({ title: streamedTitle }: { title?: string }) {
const [title, setTitle, { isPending, flush }] = useTamboComponentState(
"title",
"",
);
const { streamStatus } = useTamboStreamStatus();
return (
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
disabled={streamStatus.isStreaming || isPending}
/>
);
}
useTamboComponentState API
const [value, setValue, meta] = useTamboComponentState(
key, // Unique state key within the component
initialValue, // Initial value if no server state
debounceTime, // Debounce ms (default: 500)
);
| Return | Description |
|---|---|
value |
Current state value |
setValue |
Update state (supports updater functions) |
meta.isPending |
Server sync in progress |
meta.error |
Sync error (if any) |
meta.flush |
Immediately flush pending debounced updates |
setValue Patterns
// Direct value
setTitle("New title");
// Updater function
setCount((prev) => prev + 1);
When to Use Component State
- User-editable content AI should see
- Form inputs requiring persistence
- State that survives page reloads
- Streaming props that user can modify after generation
Streaming Best Practices
-
Make props optional in Zod schema:
z.object({ title: z.string().optional().describe("Card title"), items: z.array(z.string()).optional(), }); -
Show skeletons for missing data, not errors
-
Use optional chaining:
items?.map(...) -
Disable interactions until
streamStatus.isSuccess
Weekly Installs
97
Repository
tambo-ai/tamboGitHub Stars
11.1K
First Seen
Feb 5, 2026
Security Audits
Installed on
gemini-cli94
opencode94
codex93
github-copilot91
kimi-cli88
amp88