React video call integration

Add a video call to React or Next.js

Use one typed component to put a Meeto browser call inside a React application. The wrapper is SSR-safe for the Next.js App Router, supports inline or floating layouts and exposes events for your own product flow.

Install the React wrapper

Install the published package in the app that will render the call. It declares React 18 or newer as a peer dependency and uses the Meeto core widget underneath.

npm install @meeto/embed-react

Create the key before testing the component. In the widget dashboard, add both your local origin (for example http://localhost:3000) and the production origin. An origin mismatch prevents the iframe from loading even when the React code is correct.

Render an inline room

MeetoRoom owns the iframe lifecycle and gives it the height of its container. Pass the public key as embedKey; React's reserved key prop is not used for authentication.

import { MeetoRoom } from "@meeto/embed-react";

export function SupportCall() {
  return (
    <MeetoRoom
      embedKey="mk_live_…"
      roomName="support"
      style={{ height: 520, width: "100%" }}
      onJoined={(event) => console.log("joined", event.room)}
    />
  );
}

Use roomName for a persistent shared destination such as support or sales. Everyone using that configured key and room name reaches the same room. For an appointment-specific destination, use a booking page or pass an existing room code instead.

Useful MeetoRoom props
PropPurpose
embedKeyRequired public key beginning with mk_live_; restricted to allowed origins
roomNamePersistent named room shared by visitors using the same configuration
roomAn existing Meeto room code when your app already has a room
modeinline (default) or bubble for a floating call button
name / lang / accentPrefill a participant name, choose UI language or set an accent color
autoJoinSkip the lobby only for an open-door room; the browser will request media permission

Connect call events to your UI

Use the typed callback props for common states or one onEvent stream when your product has a single analytics or state handler.

<MeetoRoom
  embedKey="mk_live_…"
  style={{ height: 520 }}
  onPhase={(event) => setPhase(event.phase)}
  onParticipants={(event) => setCount(event.count)}
  onError={(event) => reportError(event.code)}
  onLeft={(event) => recordDuration(event.durationSec)}
/>
Events exposed by @meeto/embed-react
EventWhen it fires
onJoinedThe visitor enters the room; includes the room code
onLeftThe visitor leaves; includes reason and durationSec
onParticipantsThe participant count changes
onPhaseThe call enters prejoin, room, finished or error
onErrorThe widget reports a code and human-readable message

For imperative controls, use useMeetoRoom. It returns join, leave, setMicrophone and setCamera, plus a container ref. Do not call the hook from a server component; place the hook in a client component boundary.

Production checklist and limits

Allow the real origin

Add the exact scheme and host used by production. Preview deployments use different origins and need their own key entry or a separate test key.

Give the container a height

An inline iframe fills its container. A zero-height parent makes a working call look empty, so set a responsive minimum height.

Test a second browser

Join from another device or private window, grant camera and microphone permissions, and verify that your event handlers receive joined, participant and leave states.

Current plan limits for embedded calls
PlanCurrent limit
FreeUp to 10 participants; 60-minute calls; no cloud recording or AI summary
ProUp to 25 participants; no call time limit; up to 2 simultaneous meetings; recording and 10 AI-summary hours per month
All plansPowered by Meeto branding stays visible; embed key remains public and origin-locked

Media uses WebRTC encryption in transit. It is not end-to-end encrypted. Keep any API or host credentials on your server; only the origin-locked public embed key belongs in browser code. See privacy details before documenting your own data flow.

Frequently asked questions

Does @meeto/embed-react work with Next.js server rendering?

Yes. The package renders its container on the server and creates the browser widget in an effect, so an App Router page does not need dynamic import or ssr:false. The call itself still needs a browser with camera or microphone support.

Where do I get an embed key?

Create a key in the Meeto dashboard, add every production origin that will host the component, and pass the public mk_live_… key as embedKey. The key is origin-locked; do not put a server secret in the React bundle.

Can visitors join without a Meeto account?

Yes. Visitors can join from a current desktop or mobile browser without downloading an app or creating an account. The host still needs a valid embed key and the page origin must be allowed for that key.

What does the free plan include in an embedded call?

The current Free plan supports up to 10 participants and 60-minute calls. It includes the browser lobby, camera, microphone, chat, reactions and screen sharing with annotations. Cloud recording and AI summaries require a paid host, and the Powered by Meeto badge remains visible on every plan.

Put it to work

Open your Meeto account to set it up, or explore the working product first.