How to Add a Real-Time AI Avatar to a React SaaS App

A practical guide to placing a real-time AI avatar in a React SaaS product without confusing the avatar layer with your agent, data, or application workflow.

Spatius Team11 min read 分钟阅读
On this page

Adding an avatar to a React product is not just a matter of mounting another component. The useful implementation is the one in which the avatar has a clear job, the rest of the application still works if that surface is unavailable, and your existing agent and data boundaries remain intact.

Spatius is the presentation layer in that architecture. As the Spatius developer docs map explains, it converts avatar speech audio into real-time motion data and AvatarKit renders the avatar locally in the client. It does not return finished video or take ownership of your ASR, LLM, TTS, product data, permissions, tool calls, workflow decisions, turn-taking, or human handoffs. Those remain with your SaaS application, your agent framework, or your backend. Start with that boundary before choosing a React package or a transport.

Key takeaways

  • Choose the integration path before choosing the React component. AvatarKit UI and Direct Mode solve different integration shapes.
  • Use AvatarKit UI when your experience is built around its LiveKit-backed session wiring; do not describe it as a Direct Mode wrapper.
  • For Direct Mode, keep a small token endpoint on your backend. The client uses AvatarKit to connect to Motion Server, sends avatar speech audio, receives motion data, and renders locally.
  • Put the avatar behind a focused React boundary with visible loading, error, reconnect, and exit states. The rest of the product should remain usable without it.
  • Keep the source of truth for conversation, permissions, tools, and product actions in your application—not in avatar playback state.

Start with an integration decision, not a component

React is the place where the user sees the avatar. It is not, by itself, the architecture that determines how the avatar should connect. First identify where your application currently creates avatar speech audio and who owns the real-time runtime.

If your product already has…Start with…What React is responsible forWhat not to assume
A LiveKit Agents-based voice experienceThe documented LiveKit Agents integration and AvatarKit UIRendering the avatar surface and the surrounding session UIAvatarKit UI is not the same thing as Direct Mode. It wraps AvatarKit RTC setup and LiveKit session wiring.
TTS or another source of avatar speech audio, with a small client-side integration preferredDirect Mode and the AvatarKit Web SDK referenceRendering the avatar locally and connecting with a Session TokenYour token endpoint is not an agent runtime or an audio/motion relay.
A backend that must own the audio pipeline and downstream transportBackend ModeRendering what your backend delivers to the clientMore control also means your team owns the transport, recovery, and observability choices.

The distinction matters because the configuration, credentials, and failure behavior are different. Spatius documents AvatarKit UI as a React component package that wraps AvatarKit RTC setup and LiveKit session wiring. It is a good fit when that is the session model your product is using. Direct Mode is a separate standalone path: AvatarKit on the client connects to Motion Server using a Session Token.

If your product already has speech audio and does not need a LiveKit room for the avatar experience, avoid adding one solely because a React wrapper looks convenient. Conversely, if your product already uses LiveKit Agents, work from that documented integration instead of rebuilding a second client-to-server path next to it. The integration-path guide is the current source of truth for choosing between these shapes.

For comparable real-time React design decisions, Daily’s walkthroughs on building a custom video-chat app, React hooks for real-time sessions, and choosing between an app-message channel and a dedicated WebSocket are useful external reading. They describe general media-application patterns, not the Spatius integration contract.

Put the avatar in a React boundary, not in the global app shell

An avatar is usually part of one product moment: a guided onboarding task, a setup explanation, a training flow, or a support conversation. Treat it as a bounded feature in the route or feature module that owns that moment—not as a permanent dependency of the entire application shell. That approach also follows React’s guidance to keep shared product state at the closest common owner rather than hiding it inside a presentational child component: see Sharing State Between Components.

A useful component hierarchy looks like this:

Product page or workflow route
├── Product controls and task state
├── Conversation or agent panel
│   ├── transcript / text fallback
│   └── user actions and approvals
└── Avatar experience boundary
    ├── connection and lifecycle state
    ├── avatar canvas or AvatarKit UI surface
    ├── loading and connection status
    ├── retry / leave / alternate-mode controls
    └── localized error fallback

The outer page should own product facts: which workflow the user is in, whether an action is allowed, whether an answer is still being generated, and whether a user has chosen to close the visual experience. The avatar boundary should own only the client-side presentation session and its local state.

This separation prevents a common product mistake: letting an avatar connection state become the state of the business workflow. A user may still be able to read an explanation, approve a change, or move to support even if the avatar is loading or disconnected.

The same component-boundary discipline appears in LogRocket’s guides to React error boundaries, useEffect cleanup, and Daily’s explanation of React hooks for real-time sessions. They are helpful reference points when the visual session should fail locally instead of taking the product page down with it.

Give the canvas a real layout contract

AvatarKit UI’s canvas must render inside a container with non-zero width and height; the provider waits until that container can be measured before loading the avatar. The AvatarKit UI reference documents that sizing requirement. Make that area explicit in your layout rather than relying on a collapsed flex child, a hidden tab, or a container that has no minimum height.

For a React app with server-rendered routes, treat the avatar as a browser-rendered feature and validate the Web SDK setup in the actual client build. AvatarKit Web uses WebAssembly, so your build tool must serve the .wasm asset correctly rather than inlining it into JavaScript. The Toolchain Setup guide has the current Vite and Next.js setup requirements, and the Web SDK quickstart is the smallest documented browser path to validate first.

For the browser runtime itself, MDN’s WebAssembly overview is a useful external reference. It does not replace the Spatius toolchain instructions, which remain the source of truth for AvatarKit setup.

For broader browser-rendering context, review web.dev on rendering performance, client-side rendering and interactivity, and moving work off the main thread. These resources help teams reason about a responsive React surface without implying that they change AvatarKit’s documented setup.

Keep the product and agent boundary outside the avatar

The avatar is allowed to present speech. It should not quietly acquire authority over the product.

ResponsibilityRecommended ownerWhy it stays there
User authentication and tenant accessYour SaaS applicationIt is part of your product’s identity and authorization model.
Knowledge, retrieval, and agent contextYour agent or backendThese rules determine what the response is allowed to use.
Tool calls and consequential actionsYour application or agent workflowThe application should validate permissions and keep the user in control.
TTS and the decision to speakYour agent stack or audio sourceYour product decides which approved text becomes avatar speech.
Motion generation and local avatar renderingSpatius and AvatarKitMotion Server receives avatar speech audio and returns motion data; AvatarKit renders it locally.
Human handoff, fallback, and product analyticsYour SaaS applicationThese are product decisions, not animation behaviors.

This boundary is especially important for React teams building an “AI copilot” surface. Do not make a component’s connected state mean that the agent is available, a tool call succeeded, or an account change is complete. Keep those facts in the state management and backend contracts you already trust. React’s state management guidance is useful here: the avatar can reflect product facts visually, but it should not become their source of truth.

For a deeper product-level framing, see How to Add an AI Avatar to an Existing SaaS AI Agent.

For adjacent frontend concerns, Snyk’s React and TypeScript security practices, Rollbar’s frontend error-handling guide, and Smashing Magazine’s article on React Error Boundaries and reporting are useful third-party references. They reinforce the general rule that permissions, sensitive data, and product outcomes stay outside a presentation component.

Build the connection flow for the path you actually chose

The safest React implementation makes the connection path visible in the codebase and keeps server credentials on the server.

If you use AvatarKit UI with a LiveKit session

AvatarKit UI is a React package for an AvatarKit RTC and LiveKit-backed avatar surface. Its provider receives the avatar identifiers and LiveKit connection details, then exposes the avatar session and lifecycle state to the component tree. The React UI reference documents the available canvas, loading, error, and status primitives, so the product can build a contained avatar panel without recreating that presentation plumbing.

That does not mean the React UI becomes the agent. Your LiveKit Agents worker or other documented platform runtime still owns its part of the real-time agent flow. Your app should issue or obtain the connection details through the path appropriate to that runtime, then pass only the values needed by the avatar surface. Keep product permissions and agent business logic out of the UI props.

Use this path when your architecture is already using the corresponding LiveKit-based integration. The LiveKit Agents integration guide distinguishes that platform path from standalone options, while the AvatarKit UI reference describes its provider, status, loading, error, and context behavior.

When designing the surrounding React surface, Daily’s overview of media components for React, its React Hooks announcement, and its custom video-chat example offer useful patterns for separating session UI from the rest of a product.

If you use Direct Mode in a React SaaS app

Direct Mode has a deliberately small backend requirement, as described in the Direct Mode overview:

  1. The React client requests a Session Token from your backend.
  2. Your backend uses its server-side SPATIUS_API_KEY to call the Console API and obtain that token.
  3. The client uses the Session Token with AvatarKit to connect directly to Motion Server.
  4. Your application provides avatar speech audio; AvatarKit sends it to Motion Server, receives motion data, and renders the avatar locally.

The API key does not belong in a browser bundle, browser storage, or a client-side environment variable. The Credentials guide distinguishes the server-side API Key from the client-facing Session Token. In Direct Mode, the token endpoint does not proxy the Motion Server connection, send speech audio, receive motion data, or run ASR, LLM, or TTS. It only mints the client credential. See the Direct Mode overview, Session Token API, and Session Token authentication flow for the current requirements.

This gives React a clean responsibility: request the credential when the user enters the relevant experience, initialize the client-side avatar session, and clean it up when the user leaves it. Your existing service continues to produce the speech audio and run the agent.

For the generic browser-security and cleanup aspects of that pattern, see Auth0’s Backend for Frontend overview, LogRocket’s discussion of useEffect cleanup, and Snyk’s React security practices. They are background guidance only; the Direct Mode credential behavior remains defined by Spatius documentation.

Treat speaking as an application event

The critical handoff is not “a user clicked the avatar.” It is the moment your product decides that a particular response should be spoken. The Spatius audio guidance is useful context: the input is avatar speech audio, not a substitute for your product’s microphone, ASR, or dialogue policy.

Before sending speech to the avatar layer, your application should already have decided:

  • whether the response is appropriate to speak in this product context;
  • whether the current user may receive the underlying information;
  • whether the response contains a request for confirmation, a product action, or a handoff that needs visible controls;
  • what the text and non-avatar fallback should be if the visual surface is unavailable.

In a Direct Mode flow, the client-side AvatarKit connection sends the resulting avatar speech audio to Motion Server; the Direct Mode Web guide is the relevant client path. In a LiveKit Agents flow, use the documented LiveKit Agents client integration rather than attempting to emulate Direct Mode inside the UI. In both cases, Spatius remains downstream of the decision to speak; it does not decide what the agent says or what the user is allowed to do.

This is also why an important instruction or confirmation should not exist only as animated speech. Keep the transcript, controls, and task result in your normal React UI. That makes the workflow understandable when audio is muted, the avatar is still loading, or a user prefers another interaction mode.

For more general real-time UI trade-offs, compare Daily’s discussion of data channels versus dedicated WebSockets, its tips for browser performance in media apps, and web.dev’s guide to off-main-thread work. These are useful when planning the surrounding application, not as evidence of a Spatius transport feature.

Design lifecycle, loading, and error states as product states

The avatar surface is an asynchronous client feature. Plan the state transitions before you style the first frame. Spatius documents the underlying stages in its client lifecycle; React must still make the product-facing state of each stage understandable.

StateWhat the user should seeWhat the React feature should do
Not requestedThe normal task UI, with a clear way to start the guided experience if it is optionalDo not create an unnecessary avatar session.
Initializing or connectingA compact loading state that explains what is preparing; keep the transcript and product controls availableReserve canvas space and prevent duplicate connection attempts.
ConnectedThe avatar, a simple connection indicator, and clear user controlsKeep business actions in the surrounding product UI.
Avatar errorA local error panel with retry and an alternate path, such as text or standard support UIRecord a non-sensitive diagnostic event; do not crash the page or block the workflow.
Disconnected or user exitedA clean return to the normal product stateDisconnect or clean up the client session, then make re-entry deliberate.

With AvatarKit UI, use the supplied loading, error, and status pieces—or their documented state and callbacks—to make these transitions visible. A React Error Boundary can protect the surrounding page from a rendering failure inside the avatar subtree, but it does not replace runtime connection handling. Use React’s effect lifecycle guidance when you clean up a client session on unmount or user exit. Treat connection, initialization, reconnect, and microphone-publishing failures as asynchronous states that your avatar boundary handles explicitly.

The Client Lifecycle guide, Client State & Events reference, and AvatarKit UI reference describe the documented lifecycle, state callbacks, and available UI behavior. Keep a separate product fallback for any failure that prevents the visual experience from starting.

The corresponding general frontend practice is covered by LogRocket’s error-boundary guide, Smashing Magazine’s error reporting pattern, Rollbar’s frontend error guide, and Daily’s advice on real-time media performance. Use them to shape observability and fallback behavior around the avatar—not to collapse all failures into one generic error.

Verify the browser build before debugging the conversation

When an avatar does not appear, teams often inspect the prompt, agent, or TTS first. In a React Web integration, start with the browser surface and the integration path instead. The Web SDK quickstart gives a small known-good Direct Mode baseline before you debug your larger application.

CheckWhy it matters
The correct integration path is in useA LiveKit-backed UI setup and a Direct Mode setup do not share the same connection model.
The avatar container has measurable width and heightAvatarKit UI waits for a measurable canvas container before loading.
The WebAssembly request succeedsAvatarKit Web requires .wasm files to be served as external assets with the correct MIME type.
The client uses a Session Token only where Direct Mode requires itThe server-side API key must remain on your backend.
Your app has a visible non-avatar fallbackA product task must not disappear because a visual layer is unavailable.
Logs distinguish product failure from avatar-session failureA failed tool call, a missing transcript, and a disconnected avatar need different owners and fixes.

Do this verification in a deployed-like build, not only in a local hot-reload session. The Web SDK Toolchain Setup specifically calls out failed .wasm requests and incorrect MIME types as common causes of initialization failure. If the SDK reports a client-side issue, map it to the documented client error and recovery guidance before treating it as a product or agent failure.

For a wider view of browser-runtime checks, see web.dev’s rendering-on-the-web guide, its discussion of client-rendering trade-offs, and Daily’s React real-time app walkthrough. They help frame testing around the actual browser surface rather than only the server-side agent.

A focused implementation checklist

  1. Choose the path first. Confirm whether the feature belongs in Direct Mode, a documented LiveKit Agents integration, or Backend Mode.
  2. Define the feature boundary. Keep the avatar in the route or product module that owns the user moment.
  3. Keep the secret server-side. For Direct Mode, create a backend endpoint that mints Session Tokens; do not expose SPATIUS_API_KEY to the client.
  4. Reserve a real canvas area. Give the avatar container a measurable width and height before initialization.
  5. Connect only after the user moment is ready. Avoid initializing a session solely because the global app shell mounted.
  6. Keep the transcript and task controls independent. The user should be able to understand, continue, leave, or get help without the avatar.
  7. Handle loading and errors locally. Use visible status, retry, and alternate-mode controls instead of a blank canvas or a full-page failure.
  8. Verify the production build. Check the WebAssembly asset, credentials, lifecycle behavior, and your own product fallback in a realistic environment.

As a final cross-check, web.dev’s guidance on main-thread performance, Daily’s tips for real-time browser performance, and LogRocket’s article on effect cleanup are useful reminders to test the feature as a long-lived client session rather than a static component.

Frequently asked questions

Can I use AvatarKit UI for Direct Mode?

Do not treat it as a Direct Mode wrapper. AvatarKit UI is documented as a React package that wraps AvatarKit RTC setup and LiveKit session wiring. Direct Mode is a separate path in which the client-side AvatarKit connects directly to Motion Server with a Session Token. Choose the one that matches your runtime, then follow its current documentation.

Does adding an avatar to React add an AI agent to my app?

No. As the developer docs map explains, Spatius converts avatar speech audio into motion data and AvatarKit renders the avatar locally. Your application, agent framework, or backend continues to own ASR, LLM, TTS, context, retrieval, permissions, tool calls, workflows, turn-taking, and handoff.

Where should the Direct Mode Session Token be created?

Your backend should obtain it through the documented Session Token API flow using the server-side API key. The React client requests the Session Token from your backend and uses it for the Motion Server connection. Do not ship the API key to the browser.

Why can the page work while the avatar is blank or still loading?

The avatar is a separate client-side surface with its own canvas, WebAssembly assets, connection state, and runtime error path. Check the canvas dimensions, the browser’s .wasm response, and the selected integration path before changing your agent logic. The surrounding product UI should remain useful while that surface recovers.

Make the avatar a useful part of the product—not the product’s control plane

A good React integration makes an avatar feel native to one useful task while preserving the product architecture behind it. Pick the right path, put the visual session inside a focused component boundary, and let the rest of your application remain the owner of intelligence, data, and workflow decisions.

For teams refining the broader UI architecture, Daily’s React media-component patterns, Rollbar’s frontend error-handling guidance, and Snyk’s React security practices are relevant external reading alongside the product-specific sources above.

For the wider rollout and recovery plan, see How to Pilot an AI Avatar in Your SaaS Product and How to Handle Waiting, Errors, and Human Handoffs in an AI Avatar Experience.

If you are evaluating a real-time avatar for an existing SaaS experience, request a demo.

Sources

Selected third-party reading

Related Articles