Runnable reference product

Build the product UI above the run protocol

The React example demonstrates the missing product lifecycle above Heddle's remote protocol. It is a reference application, not a React component package or required frontend architecture.

Customization depth

Product UI

Hosting depth

React, Vite, and React Query reference

Documentation status

Runnable reference

Assumptions

  • The hosted service, public schemas, and REST/SSE API are already available.
  • The browser supports streaming `fetch` and the product can maintain a stable conversation ID.
  • The example's React, Vite, React Query, and AI Elements choices match your evaluation or can be translated into your existing frontend stack.
Heddle owns
  • Conversation persistence, run identity, ordered replay, cancellation, terminal semantics, protocol validation, and HTTP/SSE mechanics.
  • Cursor, duplicate, gap, terminal, and reconnect calculations through the remote consumer.
Your product owns
  • Authenticated conversation access, server session endpoints, public field allowlists, and browser storage choice.
  • Server-state queries, optimistic messages, rendered activity, retry and error UX, notifications, and visual design.
  • Deployment, accessibility decisions, product result application, and every business workflow around the agent.

What the reference proves

The final hosted example is a small working product above the REST/SSE protocol. It demonstrates:

  • stable session identity and server-backed message hydration;
  • immediate optimistic rendering of an accepted user prompt;
  • assistant text separated from safe tool and lifecycle activity;
  • discovery of an active run after browser reload;
  • bounded reconnect with visible failure and manual retry;
  • explicit stop and a visible cancelled terminal;
  • terminal-triggered refresh of durable messages;
  • a second prompt continuing the same persisted session;
  • idle-only reset with accessible confirmation.

Keep server state and live run state distinct

The reference uses React Query to read the durable conversation from the host API. A run is a separate live resource. Starting a run writes the accepted runId into the cached conversation and appends an optimistic user message. Receiving a terminal clears the active run and refreshes durable messages from the server.

This division prevents the browser from treating streamed text as the durable conversation record. If a terminal arrives but the refresh fails, the UI reports that specific reconciliation error instead of pretending that the stream itself was persisted.

Persist cursor and presentation together

A reload-safe client must checkpoint both delivery progress and the projection already shown to the user:

TypeScript
type RunCheckpoint = {
  runId: string
  afterSequence: number
  assistantText: string
  activities: ActivityView[]
}

Restoring only afterSequence would ask the server to skip accepted events without reconstructing the assistant text and activities those events produced. Advance the cursor and rendered projection atomically. Validate stored browser state before trusting it, discard malformed checkpoints, and degrade visibly when storage is unavailable.

The checkpoint is cleared after a terminal or conversation reset. If the server reports a different active run than the stored checkpoint, discard the old checkpoint rather than applying one run's projection to another.

Compose the remote client; do not wrap the protocol in UI state

The product client exposes Heddle's start, subscribe, and cancel operations and separately implements host-specific conversation read and reset calls. Session APIs are not smuggled into the generic run client.

The React hook owns the real browser lifecycle: aborting a subscription on unmount, accepting events in order, persisting checkpoints after rendering, scheduling retries, refreshing on terminal, stopping, and resetting. Heddle's remote services remain framework-neutral underneath it.

Rendering and accessibility

Render generated Markdown through a safe Markdown component instead of raw HTML or plain text. Keep assistant prose separate from tool and lifecycle summaries so sensitive inputs and results are not accidentally displayed. Expose loading, starting, running, stopping, error, and ready states; use live regions for status; disable submit/reset actions when their lifecycle preconditions are not met.

The reference includes trimmed AI Elements message components, but syntax highlighting, mathematics, Mermaid, and CJK plugins are intentionally omitted. Add only the rendering capabilities your product needs.

Replace the example choices

React, Vite, React Query, local storage, AI Elements, and the visual design are replaceable host decisions. If your product already uses Next.js, Vue, Svelte, Solid, Redux, Zustand, XState, or another query library, preserve the lifecycle invariants in that architecture instead of installing the sample stack.

The build-time bearer token is only for the guarded local demo server and is visible to the browser. Production authentication must use the product's existing session or token design. The reference does not invent approval, billing, rate-limit, or deployment policy.

Verification boundary

The example is compiled as part of the Heddle build, and critical checkpoint validation and safe activity projection have unit coverage. It is not an official React SDK or a promise that every product flow has browser end-to-end coverage.

Canonical sources