Adding a Talking Employee Onboarding Guide to a Vue 3 App with LiveKit

Build a Vue 3 LiveKit onboarding guide with synced avatar video, backend voice agent, and session management.
Introduction
Adding a talking onboarding guide to a Vue 3 app is mostly a systems problem, not a UI problem. You need a frontend that can render an avatar video surface, a realtime transport for audio and video, and an agent loop that can listen, decide what to say next, and speak without feeling laggy. If you already have a voice assistant, the missing piece is usually the face: synchronized lip motion, low-latency streaming, and a sane way to keep the avatar aligned with the agent state.
In this post, I’ll show the practical shape of that integration in Vue 3 with LiveKit. By the end, you should understand how to wire the browser client, how the agent side fits together, and where a realtime avatar layer belongs in the architecture. I’ll also show where Protoface fits when you want to add a synced talking face without building the avatar pipeline yourself.
What you’re building
For an employee onboarding guide, the usual interaction model is:
The user enters a page in your Vue app and joins a LiveKit room.
The agent receives microphone audio, transcribes or reasons over it, and generates speech.
The browser plays the agent’s audio and renders a talking video face that is synced to that speech.
The important part is synchronization. If the avatar is just a looping video, it will look disconnected from the agent. If the avatar is driven by the agent’s actual speech output, you get believable timing, mouth motion, and a much better “guided walkthrough” experience.
This architecture is usually built on WebRTC end-to-end. LiveKit handles media transport and room state. Your agent runs in a backend process, and the browser subscribes to the agent’s audio/video tracks. The avatar layer either produces video directly from the agent’s speech stream or attaches to the voice agent as a separate synchronized video source.
Vue 3 client: join the room and render the guide
On the frontend, keep the job small: connect to the room, publish the user microphone, and render the agent’s published tracks. Don’t put any secrets in the browser. The browser should receive a short-lived LiveKit access token from your backend, then use the LiveKit client SDK to join.
A minimal Vue component looks like this at a high level:
That’s intentionally barebones. In a real app you’ll also want:
Mic permission handling and a clear “start session” action.
State for reconnecting if the user changes network.
Track cleanup when the component unmounts.
A fallback if video is unavailable, such as an audio-only mode.
For onboarding specifically, it helps to structure the UI around steps rather than freeform chat. The guide can explain account setup, point to the right controls in the app, and ask a small number of guided questions. That reduces turn-taking ambiguity and makes the interaction more useful than a generic Q&A bot.
Agent side: voice first, avatar second
On the backend, keep the voice agent authoritative. The agent should decide when to listen, when to speak, and what content to expose to the avatar layer. In a LiveKit-based setup, the agent typically runs as a worker process that joins the same room, receives user audio, and publishes its own media tracks back into the room.
The main technical constraint is latency. Once the agent finishes generating a response, the audio and the avatar motion need to appear as one coherent output. If speech generation is slow, the avatar will either move too early or sit frozen. That is why it’s better to drive the face from the same synthesized speech stream the agent is using, rather than treating it as a separate animation problem.
From a product perspective, onboarding has a few predictable turns:
Greeting and identity confirmation.
Orientation: “Here’s where billing lives,” “This is how to reset MFA.”
Task-specific guidance based on role or department.
Escalation when the guide cannot answer confidently.
If you’re already running a LiveKit voice agent, the avatar layer should be a drop-in addition, not a separate code path. You want the same agent logic, the same turn detection, and the same interruption handling. The avatar should reflect the agent’s speaking state, not invent its own.
Where the realtime avatar layer fits
This is the part people often rebuild unnecessarily. A realtime avatar service sits between the agent’s speech output and the browser’s video renderer. The service takes the agent’s utterance or audio stream, produces a lip-synced talking face, and publishes that as a media track. The browser just subscribes and renders it like any other LiveKit video track.
If you are using a LiveKit voice agent and want the agent to have a synchronized video face, the relevant integration is the LiveKit Agents plugin. The Python package livekit-plugins-protoface is designed for exactly that use case. In practice, you add the plugin to the agent process, configure the avatar/session details, and let the agent publish the avatar track alongside audio. The exact fields and setup depend on your session and avatar configuration, so follow the docs for the current API shape.
If you want to explore the plugin code and examples directly, start with the GitHub repo for the LiveKit integration: https://github.com/protoface-ai. For the plugin package itself, the PyPI distribution is the canonical install target, but the code examples in the repository are usually the fastest way to see how the pieces connect.
Backend operations: create sessions, keep secrets server-side
For onboarding guides, you usually need some session lifecycle management: create an avatar session when a user starts, attach metadata like tenant or role, and tear it down when the meeting ends. That belongs on the server, not in Vue.
Protoface exposes a REST API for avatar and session management, authenticated with API keys. The browser should never see that key. A backend endpoint can create the session and return only the minimal information the client needs.
The response shape is documented in the docs, and that is the source of truth for fields such as session identifiers, embedding parameters, and any avatar-specific options. Keep your server logic thin: create or fetch the session, hand back a short-lived token or room-specific details, and let the client connect.
If you prefer programmatic control over avatars and sessions, the Python SDK is also available. That is useful when you want to provision sessions as part of onboarding workflows, admin tooling, or internal automation.
Two operational details matter here. First, rate limit session creation so a refresh storm does not create duplicates. Second, make session teardown explicit so long-running rooms do not leak usage. In a support or onboarding flow, “disconnect” should mean the backend knows the interaction is over.
Trade-offs and implementation gotchas
A talking guide sounds simple, but a few details usually bite teams the first time:
Audio/video sync is more important than avatar realism. A slightly simpler face with tight lip-sync will feel better than a highly detailed avatar with lag.
Turn detection changes the UX. If the agent interrupts too aggressively, the avatar will appear impatient. If it waits too long, the experience feels sluggish.
Browser autoplay rules still apply. You may need a user gesture before playing audio/video, especially on first load.
Keep onboarding scoped. This is not a general-purpose chat UI. Use short, task-oriented prompts and predictable navigation cues.
It also helps to decide early whether the face is core to the workflow or just a nice-to-have. If it is core, invest in proper reconnect behavior, observability, and per-tenant session tracking. If it is decorative, keep the integration simple and make sure the page still works when the avatar track is unavailable.
Conclusion
The cleanest way to add a talking onboarding guide to a Vue 3 app is to treat it as a realtime media problem: the browser joins a room, the agent owns the conversation, and the avatar is just another synchronized output of that agent. Vue handles rendering and local interaction; LiveKit handles transport; the avatar layer turns speech into a face.
If you want to build this yourself, start small: get a LiveKit room working in Vue, verify the agent can publish audio, then add the avatar track and make sure it stays in sync under reconnects and network variation. For the current integration details, session APIs, and examples, see docs.protoface.com. If you want to move faster, the quickstarts in the public repo linked from the docs are the shortest path from prototype to something you can actually ship.
