Tambo Lockup

Component Streaming Status

Track individual prop streaming status with fine-grained control over rendering.

The useTamboStreamStatus hook lets you track both overall and per-prop streaming status, so you can show loading or completed states for each prop as they arrive.

How Does It Work?

Without per-prop tracking, you're forced to show nothing until all props are ready (poor UX) or show everything with default values (potentially confusing). This hook gives you granular control over what renders when.

basic-usage.tsx
import { useTamboStreamStatus } from "@tambo-ai/react";

function Note({ title, content, createdAt }) {
  const { streamStatus, propStatus } = useTamboStreamStatus();

  // Wait for everything to complete
  if (!streamStatus.isSuccess) return <Spinner />;

  return (
    <div>
      <h3>{title}</h3>
      <p>{content}</p>
      {propStatus["createdAt"]?.isSuccess && <p>{createdAt}</p>}
    </div>
  );
}

Building on Previous Concepts

This guide builds on Streaming and Response Component Streaming. We recommend reading those first.

Status Types

Global Stream Status (streamStatus)

Tracks the overall state of the entire component:

FieldTypeDescription
isPendingbooleanNo tokens received yet, show initial loading state
isStreamingbooleanActive data transmission (generation OR props streaming)
isSuccessbooleanAll props completed successfully
isErrorbooleanAny fatal error occurred in generation or props
streamError?ErrorFirst error encountered during streaming

Per-Prop Status (propStatus)

Tracks individual prop streaming states:

FieldTypeDescription
isPendingbooleanNo tokens received for this specific prop yet
isStreamingbooleanPartial content received, prop is still updating
isSuccessbooleanProp finished streaming successfully
error?ErrorError that occurred during streaming of this prop

Usage Patterns

Wait for Everything to Complete

wait-for-all.tsx
function ArticleCard({ title, content, author }) {
  const { streamStatus } = useTamboStreamStatus();

  if (streamStatus.isPending) return <div className="animate-pulse h-32" />;
  if (streamStatus.isError)
    return <div>Error: {streamStatus.streamError?.message}</div>;
  if (!streamStatus.isSuccess) return <Spinner />;

  return (
    <div>
      <h2>{title}</h2>
      <p>{content}</p>
      <span>By {author}</span>
    </div>
  );
}

Progressive Rendering

Show each prop as it becomes available:

progressive-rendering.tsx
function DashboardWidget({ title, data, config }) {
  const { propStatus } = useTamboStreamStatus();

  return (
    <div>
      {propStatus["title"]?.isPending && <div className="animate-pulse h-6" />}
      {propStatus["title"]?.isSuccess && <h3>{title}</h3>}

      {propStatus["data"]?.isStreaming && <Spinner />}
      {propStatus["data"]?.isSuccess && <DataChart data={data} />}

      {propStatus["config"]?.isSuccess && <ConfigPanel config={config} />}
    </div>
  );
}

Advanced Patterns

Handle errors and group related props:

advanced-patterns.tsx
function BlogPost({ title, author, content, tags }: BlogPostProps) {
  const { propStatus } = useTamboStreamStatus<BlogPostProps>();

  return (
    <article>
      {/* Group header content */}
      {propStatus["title"]?.isSuccess && propStatus["author"]?.isSuccess && (
        <header>
          <h1>{title}</h1>
          <span>By {author}</span>
        </header>
      )}

      <div>{content}</div>

      {/* Handle errors gracefully */}
      {propStatus["tags"]?.error && <p>Failed to load tags</p>}
      {propStatus["tags"]?.isSuccess && (
        <div>
          {tags.map((tag) => (
            <span key={tag}>{tag}</span>
          ))}
        </div>
      )}
    </article>
  );
}

When to Use Component Streaming Status

✅ Use When

  • Different props have different loading times
  • You want progressive rendering
  • You need fine-grained error handling
  • You have complex UI that depends on multiple props

❌ Don't Use When

  • You only have simple text content
  • You're doing SSR/SSG (client-side only)

Integration with Other Tambo Features

With Stream Status Provider

with-provider.tsx
import { TamboPropStreamProvider, useTamboStreamStatus } from "@tambo-ai/react";

function EnhancedComponent({ title, content, metadata }) {
  const { streamStatus } = useTamboStreamStatus();

  return (
    <TamboPropStreamProvider
      data={{ title, content, metadata }}
      streamStatus={streamStatus}
    >
      <TamboPropStreamProvider.Loading streamKey="title">
        <div className="animate-pulse h-6" />
      </TamboPropStreamProvider.Loading>

      <TamboPropStreamProvider.Complete streamKey="title">
        <h1>{title}</h1>
      </TamboPropStreamProvider.Complete>

      <TamboPropStreamProvider.Complete streamKey="content">
        <div>{content}</div>
      </TamboPropStreamProvider.Complete>
    </TamboPropStreamProvider>
  );
}

Stream Status Provider

The Stream Status Provider provides declarative streaming state management with built-in loading and complete states for individual props.

With Streaming Props Hook

with-streaming-props.tsx
import { useTamboStreamingProps, useTamboStreamStatus } from "@tambo-ai/react";

function StatefulComponent({ streamedTitle, streamedContent }) {
  const { propStatus } = useTamboStreamStatus();
  const [state, setState] = useState({ title: "", content: "" });

  useTamboStreamingProps(state, setState, {
    title: streamedTitle,
    content: streamedContent,
  });

  return (
    <div>
      <h1>{state.title}</h1>
      {propStatus["content"]?.isSuccess && <p>{state.content}</p>}
    </div>
  );
}

Streaming Props into State

The Streaming Props into State feature allows you to automatically update component state as props stream in, providing seamless integration with React state management.