Header Logo

Embedding a Realtime Receptionist Avatar in SvelteKit with an iframe: No-Backend Setup

Embedding a Realtime Receptionist Avatar in SvelteKit with an iframe: No-Backend Setup

Embed a realtime receptionist avatar in SvelteKit with a responsive iframe, origin allowlisting, and no backend or API key exposure.

Introduction


If you want a receptionist, support agent, or product guide with a visible face, the browser embed is often the fastest path from prototype to something you can ship. The hard part is usually not rendering video; it is doing it without building a backend just to broker sessions, keep secrets out of the client, and enforce basic access controls.


This post shows how to embed a realtime receptionist avatar in a SvelteKit app using a customer-managed <iframe> flow. By the end, you should understand the moving pieces: how the embed is isolated from your app, how parent-origin allowlisting and per-embed settings work, what the browser actually needs to do, and where the trade-offs are compared with a custom client integration.


We will keep the implementation intentionally simple: a SvelteKit page that renders an iframe, some URL parameters or embed configuration, and enough front-end logic to handle layout and messaging. No backend in your app, no API key in the browser.


Why iframe-based embeds are a good fit for a receptionist avatar


A realtime avatar is not just a video element. Under the hood, you are usually dealing with a media session with low-latency audio and video, conversational turn-taking, and stateful instructions. In a voice-agent setup, the avatar must stay synchronized with the agent’s speech, which is why these systems are typically built on WebRTC or a similar real-time transport rather than plain HLS/DASH video.


That matters for your app architecture. If you try to wire everything directly into your front end, you end up managing session creation, auth, rate limits, and user scoping in a place that is hard to secure. An iframe works because it creates a boundary:


  • Your SvelteKit app owns the page and the surrounding UI.

  • The embedded avatar app owns the media session and any sensitive session bootstrap.

  • The browser enforces origin isolation, and the embed can explicitly allow only approved parent origins.


For a receptionist use case, that usually means you can ship a “talk to the assistant” panel on a marketing site, a product dashboard, or a support portal without standing up a separate service just to hand out short-lived tokens.


What the browser actually needs to do


From the browser’s point of view, the job is straightforward: render an iframe at a stable size, pass enough context for the embedded experience to know who it is serving, and optionally listen for postMessage events if you want your page to react to the avatar state.


There are a few practical constraints worth keeping in mind:


  • Origin restrictions: the embed should only load inside approved parent origins. That prevents someone from copy-pasting your iframe into a malicious site.

  • Rate limits: per-IP and duration limits help keep embedded sessions from being abused.

  • Per-embed instructions: the receptionist persona, voice, and behavior should be configured with the embed, not hard-coded into your app.

  • Responsive layout: the iframe needs an explicit height and width strategy so the video surface does not collapse on smaller screens.


In practice, you usually want the iframe to fill a card or a panel, and then let the embedded app handle mic permissions, autoplay constraints, and any internal UI.


SvelteKit implementation: a minimal, no-backend embed


In SvelteKit, the implementation can be as small as a component plus a page. The important part is that you are embedding a URL that already encapsulates the session logic; your app does not need to mint API tokens or proxy requests.


Here is a simple Svelte component that renders the frame and keeps it responsive:


<script lang="ts">

</style>
<script lang="ts">

</style>
<script lang="ts">

</style>


Then consume it from a page:


<script lang="ts">

<AvatarEmbed {embedUrl} />
<script lang="ts">

<AvatarEmbed {embedUrl} />
<script lang="ts">

<AvatarEmbed {embedUrl} />


A few implementation notes:


  • allow="camera; microphone; autoplay; fullscreen" is usually necessary for realtime media. Without it, the embedded app may not be able to request devices or start playback cleanly.

  • aspect-ratio is a better default than hard-coded pixels because it keeps the avatar stable across breakpoints.

  • If you want the avatar to sit beside chat or form fields, put the iframe in a flex or grid layout and let the browser size the panel naturally.


Handling page-level behavior in SvelteKit


One reason iframe embeds are pleasant in SvelteKit is that the page can remain mostly static. Your app can still manage shell-level concerns like route transitions, auth state for the surrounding page, and conditional rendering of the receptionist panel.


Common patterns:


  • Lazy mount the iframe: only render it when the user opens a support drawer or clicks “Talk to us.” This avoids starting a media session before the user intends to interact.

  • Persist open/closed state: use Svelte stores or local storage so the panel remembers whether it was open on refresh.

  • Guard mobile layout: on smaller screens, make the iframe full width and move supporting controls below it.


If you need to react to events from the embedded app, use window.postMessage and validate the sender origin. Do not assume any message from the browser is trustworthy. The exact message schema depends on the embed, so check the docs before wiring it into production logic.


Configuration, security, and the stuff that tends to break


The “no-backend” part does not mean “no operational concerns.” It means the embed service handles the session bootstrap for you. You still need to think about a few things:


  1. Allowlist your origin correctly. If you deploy to multiple hostnames, include all the production origins you expect to use. Miss one and the iframe will fail only in that environment.

  2. Pick sane session limits. A receptionist panel that can run forever is a billing and abuse problem. Duration limits are part of the control surface for a reason.

  3. Keep the iframe isolated in your layout. Avoid wrapping it in elements that steal pointer events or accidentally clip overflow.

  4. Test microphone permissions early. Browsers differ in how they prompt users, and autoplay policies can still trip you up if the iframe is not granted the right permissions.


Also remember that the embedded experience is only one layer of the product. The avatar’s behavior should be tuned for short, grounded interactions: greet the user, answer a question, hand off to a form, or route to human support when needed. Realtime avatars work best when they have a narrow job.


Where Protoface fits


Protoface provides the customer-managed iframe embed used for this setup, so the browser never sees an API key and your SvelteKit app does not need a backend just to launch the session. The embed supports parent-origin allowlisting, per-embed voice and custom instructions, and basic usage controls such as per-IP and duration limits.


That is the right abstraction if your goal is to add a receptionist avatar to a website, a product tour, or a support entry point without coupling the page to your own session service. If you need the implementation details, the canonical source is the documentation at docs.protoface.com.


For teams that later want a deeper integration, the same platform also exposes server-side APIs and SDKs, but for a SvelteKit page with a no-backend requirement, the iframe is the cleanest surface to start with.


Example: provisioning or inspecting an embed from the API


If you are curious what the server-side workflow looks like behind the embed, it is typically a short authenticated API call. The exact request/response fields are documented, but the shape is familiar: create a resource, receive an ID or URL, then use that in your client.


curl -X POST https://api.protoface.com/sessions \
}'
curl -X POST https://api.protoface.com/sessions \
}'
curl -X POST https://api.protoface.com/sessions \
}'


You would normally do this from a backend or a secure admin workflow, not from the browser. The point is that the iframe embed is the client-side delivery mechanism, while the API is the control plane.


Conclusion


If you need a realtime receptionist avatar in a SvelteKit app, an iframe embed is usually the least fragile architecture. It keeps the media session and sensitive configuration out of your browser code, gives you a clean security boundary, and lets you ship quickly without introducing a backend purely for avatar session management.


The practical recipe is simple: render the iframe, size it responsively, allow the media permissions it needs, and configure the embed with the right origin and behavior constraints. From there, you can iterate on the surrounding UI without constantly touching the avatar plumbing.


For setup details, integration options, and the exact embed/session fields, start with docs.protoface.com. If you want broader examples or adjacent quickstarts, the public repo index at GitHub is a good place to browse from.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.