Adding a Conversational Sales Avatar to a Next.js App with JavaScript

Build a Next.js conversational sales avatar with server-side sessions, voice-agent sync, and secure client-side playback using Protoface.
Introduction
Adding a conversational sales avatar to a Next.js app is mostly an integration problem, not a graphics problem. You need three things to work together cleanly: a text/voice conversation loop, a realtime video face that stays synchronized with the agent’s speech, and a browser UI that doesn’t leak secrets or add unnecessary latency.
In practice, the avatar should behave like a normal part of your product: it should load fast, start talking when the agent has something to say, animate naturally while audio is playing, and fail gracefully when the network is slow or the session drops. By the end of this post, you should have a mental model for how to wire that up in Next.js, what runs in the browser versus your backend, and where Protoface fits into the architecture.
Start with the right architecture
The first design choice is where the conversation and avatar session live. For a sales assistant, the cleanest pattern is usually:
The browser hosts the Next.js UI and renders the avatar surface.
Your backend creates or authorizes a realtime avatar session.
A voice agent or LLM loop produces responses.
The avatar receives the agent’s output as synchronized speech/video.
That separation matters because the browser should not hold long-lived API keys, and because realtime media flows are easier to manage when session creation happens server-side. In Next.js, that usually means an API route or server action that mints whatever session metadata the frontend needs, followed by a client component that attaches to the avatar surface.
For sales use cases, keep the agent stateful enough to remember the current lead context, but not so stateful that a reconnect breaks the whole experience. A good mental model is: the avatar is the presentation layer, the voice agent is the conversational brain, and your app backend is the system of record for user/session data.
Build the browser surface carefully
In Next.js, the avatar component should almost always be client-side. The browser is responsible for playback, rendering, and interaction events; the server is responsible for authenticating and creating the session. If you are using an iframe-based embed, this is even cleaner because the avatar runs in a customer-managed embed with no backend required on your side and no API key exposed in the browser.
For a custom Next.js UI, the usual structure is a client component that loads the avatar, waits for the session data from your backend, and then connects. Keep the UI conservative:
Render a fallback state while the session initializes.
Do not assume video will autoplay; respect browser autoplay rules.
Handle “audio ready” and “session connected” as separate states.
Expose a reconnect path if the websocket or media connection drops.
It is worth treating the avatar as a realtime media peer, not as an image widget. That means you should expect connection setup time, buffering, and occasional renegotiation. The frontend should not block the rest of the sales page while the avatar initializes.
Server-side session creation and secret handling
Whatever avatar/session primitive you use, create it on the server. That keeps your API key out of the browser and gives you a place to enforce your own business logic: which logged-in users can start sessions, what voice or prompt they get, and how long a session may run.
Protoface exposes a REST API for avatar and session management, authenticated with an API key. A typical server-side request looks like this:
The exact fields depend on the API shape in the docs, but the pattern is the important part: create the session server-side, return only the minimal client data needed to connect, and keep the secret material behind your backend boundary. If you are building a sales assistant that lives on a marketing site, this is the difference between a safe integration and a credential leak waiting to happen.
What actually makes the avatar look synchronized
Speech/video sync in this kind of product is usually about keeping three clocks aligned: token generation from the model, audio playback in the browser, and the avatar’s lip and facial animation. The avatar should not independently “guess” what the speaker is saying; it should be driven by the same output stream that produces the audio.
For developers, the practical implications are:
Generate responses in chunks if the platform supports streaming, so the avatar can start moving before the full answer is done.
Avoid buffering too aggressively in the client; low latency matters more than perfect preloading.
Prefer one authoritative conversation session over ad hoc client-side updates.
Keep the assistant’s text and audio aligned so the visual mouth movement matches the spoken content.
If you are coming from a normal chat UI, this is the main mindset shift: you are no longer just rendering messages. You are orchestrating a realtime media session where latency and synchronization are product features, not implementation details.
Integrating a voice agent backend
If your sales agent already runs in a voice-agent stack, the avatar should slot into that stack rather than replacing it. A common pattern is to let the agent own the conversation loop and inject the avatar as the video surface for the same session. That keeps the agent logic untouched and lets the avatar simply mirror the speech output.
Protoface has a LiveKit Agents plugin for exactly this style of integration. If your agent already speaks over LiveKit, adding a synchronized face is usually a matter of wiring the plugin into the agent pipeline rather than building a separate media subsystem. The plugin lives in the Python package index as pipecat-protoface, and the examples and source are available in the relevant GitHub repositories and docs.
A minimal Python-side shape looks like this:
Again, treat the snippet as illustrative; the concrete method names and returned fields are defined in the docs. The point is to show the boundary: your backend creates the session, your frontend consumes a short-lived client token or equivalent, and the live voice stack drives the experience.
One practical Protoface path for Next.js
For a Next.js app, the most direct path is usually a backend-created session plus a client-side embed or session bootstrap. If you want the fastest route to a working prototype, start with the public documentation at docs.protoface.com and use the quickstarts linked from the project repository to match your voice stack. If you are already on LiveKit, the plugin route is the least invasive because it keeps the voice agent as the source of truth and adds the avatar as a synchronized output.
If you do not want to expose any backend at all, the iframe embed model is the other sensible choice. It is useful for marketing sites and lightweight product experiences because the avatar session is customer-managed, the browser never sees an API key, and you can constrain behavior with parent-origin allowlists and rate limits. That trade-off is often better than building a custom frontend when the requirement is “put a talking sales rep on the page” rather than “own every pixel.”
Operational gotchas worth planning for
There are a few failure modes that show up quickly in production:
Autoplay restrictions: browsers may block audio/video until the user interacts with the page. Design for a click-to-start affordance.
Latency spikes: if the model response or media negotiation stalls, show a non-breaking fallback instead of a blank rectangle.
Session expiry: keep session TTLs explicit and reconnect logic predictable.
Prompt drift: for sales workflows, keep the assistant instructions short, specific, and versioned.
Security boundaries: never ship your API key to the browser if you are using the REST API or SDK directly.
You should also think about how the avatar fits your sales funnel. A conversational avatar that can answer product questions is useful; one that can qualify a lead, capture an email, and hand off to a human is more useful. The integration should make that handoff visible and explicit, not hidden inside the media layer.
Conclusion
The core pattern is straightforward: create or authorize the session on the server, keep the browser focused on rendering and playback, and let the voice agent drive synchronized speech and animation. Once you separate those responsibilities cleanly, a sales avatar becomes just another realtime surface in your app rather than a fragile one-off integration.
For implementation details, check the docs, start from a matching quickstart, and choose the surface that matches your architecture: REST API or SDK for server-managed sessions, a LiveKit plugin if you already run a voice agent, or an iframe embed if you want the smallest possible client footprint. The docs at docs.protoface.com are the right place to map the snippets here to the exact request and session fields you’ll use in production.
