Adding a Talking Property Tour Avatar to a Next.js Real Estate App

Build a Next.js property-tour avatar with server-side session creation, WebRTC media, and synced voice/video state.
Introduction
If you build real estate software, you already know that “touring a property” is often a chat problem disguised as a UI problem. A listing page can show photos, floor plans, and a map, but it still leaves a lot of questions unanswered: What’s the flow like? Where are the tradeoffs? Does the layout actually match the buyer’s needs?
An interactive avatar can fill that gap without forcing the user into a full call or a heavyweight video experience. In this post, we’ll build the architecture for a property-tour avatar in a Next.js app: a browser UI that connects to a realtime voice agent, renders a synchronized talking face, and keeps the actual conversation state on the server. By the end, you should know where the WebRTC boundary belongs, how to structure the frontend, and how to keep API credentials out of the browser.
What the browser should do, and what it should not do
The first design decision is where to run the conversational logic. For a property tour, the browser should be a thin client:
Render the listing page, the avatar container, and the call controls.
Request a short-lived session or join token from your backend.
Attach to the realtime media session and display the remote avatar video.
Send and receive user audio/video streams as needed.
It should not contain your long-lived API key, model routing logic, or any privileged avatar/session management calls. Those belong on the server.
This matters because realtime avatars are not just animated GIFs. The face has to stay synchronized with speech synthesis and turn-taking. In a typical setup, your voice agent produces audio in realtime; the avatar pipeline consumes that audio and emits a lip-synced video stream that is delivered back to the client over a media transport such as WebRTC. If the browser is also the place where you manage the avatar session lifecycle, you usually end up leaking credentials or coupling UI code to backend state in ways that are hard to unwind later.
Suggested Next.js shape
A practical implementation in Next.js usually has three pieces:
A listing page with the property data and a “Talk to this home” CTA.
A small client component that joins the realtime session and renders the avatar video.
A server route or server action that creates the session and returns only ephemeral join data.
You can keep the UI extremely simple. The important part is that the avatar component is isolated from the rest of the page so you can mount, unmount, and rejoin cleanly when the user switches properties.
The avatar component can initialize the realtime session from a server endpoint, then attach to the returned media room or iframe depending on which integration surface you choose. For a fully custom UI, you typically want direct media access so you can place the video next to the listing and coordinate controls such as mute, restart, or “ask a different question.”
Managing the conversation state for a property tour
A property tour is not a generic support bot. It should know the specific listing, the user’s context, and the interaction policy. The useful pattern is to construct a prompt or instruction set server-side based on the property record. For example:
Inject address, price, bed/bath count, amenities, and neighborhood notes.
Limit the avatar to facts from your source of truth.
Give it a voice and tone that fit the use case: concise, descriptive, and honest about unknowns.
Tell it how to handle questions it can’t answer, such as asking the agent to follow up.
Keep in mind that a realtime avatar session is only as good as the data you feed it. If your listing database is stale, the avatar will faithfully speak stale information. The right fix is not prompt cleverness; it is a dependable property data pipeline.
In Next.js, this usually means your server route looks up the property, composes instructions, and asks the backend avatar service to create a session. The browser only receives a session identifier or join payload. Here is a condensed example using the REST API pattern:
The exact request shape and fields depend on the docs, but the pattern is consistent: create the session on the server, then hand the frontend only the data it needs to join.
Building the frontend without over-engineering it
In the browser, keep the experience boring and reliable. Realtime media UIs fail in unglamorous ways: autoplay restrictions, permission prompts, mobile Safari edge cases, and unmounted components that leak media tracks. Plan for those from the start.
A good client component should:
Request microphone permission only when the user explicitly starts the tour.
Show connection state transitions: idle, connecting, live, reconnecting, ended.
Stop local tracks on unmount.
Handle a new listing by tearing down the old session before creating a new one.
The important thing here is not the exact client library; it is the lifecycle discipline. Realtime audio/video is stateful. If your component tree changes, you need a deliberate teardown path. This is especially true in a property browser where users may jump between listings frequently.
Why the avatar should reflect the property, not just the agent
Developers often start with a generic “sales avatar,” then discover that users ask highly contextual questions: “Is the primary bedroom street-facing?” “Which way does the kitchen get light?” “How far is the train?” The most useful avatar behaves like a guided tour layer over structured property data.
That means your application should make the listing context explicit in the session. A robust prompt should include:
Hard facts from the listing system of record.
Neighborhood or commute data if you trust it.
Behavior rules: no fabrication, no pressure, no escalation unless asked.
Fallback behavior for uncertainty.
Because the avatar is realtime, the tone matters more than in a text chatbot. Short utterances, clear pacing, and low-latency responses make the tour feel interactive instead of robotic. If response times are too slow, users stop treating it like a conversation and start treating it like a spinner with a face.
Where Protoface fits
This is the part where a dedicated avatar layer saves you from assembling the whole stack yourself. The Protoface platform gives you a developer-facing realtime avatar API and a few integration surfaces depending on how much you want to own.
For a Next.js property-tour experience, the cleanest path is often to create and manage sessions on the server through the REST API, then let your app join that realtime session from the browser. That keeps API keys off the client and makes it straightforward to vary instructions per listing. If you prefer to prototype the backend in Python, the Python SDK is a reasonable place to centralize that logic; if your voice stack already runs on LiveKit Agents, the Protoface plugin can drop a synchronized talking face into the existing agent flow.
For teams that want to get a working experience in front of stakeholders quickly, the iframe embed is also useful, especially for demos or property pages that need a managed avatar without exposing backend complexity in the browser. But for a production Next.js app with a custom property UI, I would start with the server-created session model and only use the embed when the tradeoff is worth it.
Relevant docs and examples are in the documentation and the GitHub organization, with package-level notes in the plugin and SDK repos when you need implementation details.
Operational concerns: rate limits, permissions, and costs
There are a few non-obvious concerns worth handling early:
Session limits: decide how long a tour can run before it should end or reset.
Per-user access: if tours are gated behind a logged-in experience, enforce that on the server before creating the session.
Instruction safety: keep the avatar constrained to the selected property and avoid leaking internal notes.
Usage cost: since billing is tiered by quality, choose the lowest tier that meets your UX target and test latency under realistic network conditions.
Also remember that a voice agent plus avatar is an end-to-end realtime system. Your perceived quality is determined by microphone capture, network round-trip, speech synthesis latency, and video synchronization together. Optimizing only one layer rarely fixes the actual user experience.
Conclusion
A talking property-tour avatar is useful when it stays tightly scoped: property-specific, server-managed, and built as a realtime media client rather than a fancy animation. In Next.js, that usually means a clean split between property data, session creation on the server, and a small browser component that joins and renders the live avatar.
If you want to build this for real, start with your property data model, then wire up a server endpoint that creates a per-listing session and instructions. From there, you can iterate on the UI and voice behavior without changing the security model. The docs at docs.protoface.com and the quickstarts linked from the main repos are the fastest way to adapt the pattern to your stack.
