Meeto Widget: developer docs

The widget is an iframe of meeto.me with a typed postMessage bridge. All you need is a public embed key — create one in the dashboard.

Quickstart

Pick your stack, replace YOUR_KEY with your key and give the container a height — the widget fills 100% of it.

<div id="meeto-call" style="height: 520px"></div>
<script src="https://meeto.me/widget.js" data-key="YOUR_KEY" data-target="#meeto-call"></script>

npm packages: @meeto/embed-core (no dependencies), @meeto/embed-react, @meeto/embed-vue, @meeto/embed-angular. The plain widget.js script works without any build step.

Script parameters

Attributes of the <script src="https://meeto.me/widget.js"> tag (* — required). The same options exist in the JavaScript API (key, container, room, name, lang, accent, autoJoin, baseUrl) and as attributes of the <meeto-room> web component.

ParameterDescription
data-key*Public embed key (mk_live_…) from the dashboard.
data-modeinline (default, iframe in your container) or bubble — a floating call button in the page corner; no container needed.
data-targetCSS selector of the container. Without it a 520px-high block is created right after the script tag.
data-room-namePersistent named room: everyone with this snippet meets in the same room («support»). The key owner joins as host from the dashboard.
data-positionBubble corner: bottom-right (default) or bottom-left.
data-labelaria-label of the bubble button (the widget doesn’t know your site’s language).
data-roomExisting room code (meeto.me/<code>). Without it the widget creates a room itself and reuses it within the tab.
data-nameParticipant name prefilled in the lobby.
data-langWidget interface language (en, ru, de, …). Default — the visitor’s browser language.
data-accentAccent color, hex (e.g. #27D6AA).
data-auto-joinSkip the lobby and join immediately (open-door rooms only; camera and mic start enabled).
data-base-urlMeeto address for self-hosted installations.

Room links stay valid: any widget room can also be opened at meeto.me/<code>.

Events and methods

Subscribe via widget.on(type, handler) (returns an unsubscribe function), the onEvent option, framework component props, or meeto:* CustomEvents of the <meeto-room> element.

const widget = new MeetoWidget({ key: "mk_live_…", container: "#call" });
const off = widget.on("joined", (e) => console.log(e.room));
widget.on("participants", (e) => console.log("in call:", e.count));
EventPayload
readythe widget loaded and connected to the page
phase{ phase: "prejoin" | "room" | "finished" | "error" }screen changed (lobby, call, finished, error)
joined{ room, identity }the visitor joined the call
left{ reason, durationSec }the visitor left the call (reason: left, ended, kicked, connection)
participants{ count }participant count changed
error{ code, message }the widget can’t start (bad key, unregistered domain, …)

Widget instance methods:

MethodDescription
join(name?)Join the call from the lobby programmatically (open-door rooms).
leave()Leave the call.
setMicrophone(on)Toggle the microphone during the call.
setCamera(on)Toggle the camera during the call.
destroy()Remove the iframe and all subscriptions.

Server API

For server-side flows (create rooms from your backend, mail out links, decide who becomes the host) use the secret key mk_secret_… — it’s shown once when you create the embed:

curl -X POST https://api.meeto.me/api/embed/rooms \
  -H "Authorization: Bearer mk_secret_…"
# → 201 { "slug": "misty-fox-42", "hostSecret": "…" }

hostSecret makes its bearer the room host: pass the room to the widget via data-room, and hand hostSecret only to your own staff. Requests with the secret key skip the domain check — never expose it in browser code.

Mobile SDKs (iOS / Android)

Native wrappers embed the same widget into your app: a WebView with a typed event/command bridge. Register the app origin app://<bundle-id> in the key’s domains.

iOS (Swift Package, iOS 14+)

// Xcode → File → Add Package Dependencies…
https://github.com/meeto-app/meeto-widget-ios.git   // from: 0.1.2
import MeetoWidget

MeetoWidget(config: .init(key: "mk_live_…", roomName: "support")) { event in
    if event.type == "left" { /* close the screen */ }
}

Swift Package; add NSCameraUsageDescription and NSMicrophoneUsageDescription to Info.plist.

Android (Kotlin, minSdk 24)

// settings.gradle.kts
dependencyResolutionManagement { repositories { maven("https://jitpack.io") } }

// module's build.gradle.kts
dependencies { implementation("com.github.meeto-app:meeto-widget-android:0.1.3") }
val widget = MeetoWidgetView(this)
widget.onEvent = { event -> if (event.type == "left") finish() }
container.addView(widget)
widget.load(MeetoWidgetConfig(key = "mk_live_…", roomName = "support"))

Gradle module; declare CAMERA / RECORD_AUDIO / INTERNET and request runtime permissions before showing the widget.

Events (ready, joined, left, participants, error) and commands (join, leave, setMicrophone, setCamera) are identical to the web SDK.

Source code and releases: meeto-app/meeto-widget-iosmeeto-app/meeto-widget-android

WordPress plugin

Add the widget to a WordPress site without writing code: a floating call button on every page or an inline call via a shortcode.

Download meeto-widget.zip
  1. In the WordPress admin, open Plugins → Add New → Upload Plugin and upload the zip.
  2. Activate the plugin and open Settings → Meeto Widget.
  3. Paste your embed key (with your site's domain added to it) — the call button is live.

For an inline widget, disable auto-insert in the settings and put the shortcode into any page: [meeto_widget room_name="support" height="600"]

Limits

Widget rooms follow the plan of the key owner:

  • Free — up to 10 participants, group calls up to 60 minutes, up to 1080p.
  • Pro — up to 25 participants, no time limit, up to 4K, and the “Powered by Meeto” badge can be hidden.

Security

  • The public key is not a secret: it’s visible in your page source, that’s by design.
  • The widget only works on domains registered for the key. The browser reports the embedding site’s origin in a way pages can’t forge (postMessage event.origin), and the Meeto backend checks it.
  • The secret key mk_secret_… is stored hashed and shown only once. Use it exclusively server-to-server.
  • A leaked or unused key can be revoked in the dashboard at any moment — the widget stops instantly.

FAQ

Which frameworks are supported?

Any. Plain HTML via widget.js, React/Next.js, Vue/Nuxt and Angular via npm packages, everything else via the <meeto-room> web component.

Does it work with a self-hosted Meeto?

Yes: point data-base-url (or the baseUrl option) at your installation.

Can I remove “Powered by Meeto”?

On the Pro plan — toggle it per key in the dashboard. On the free plan the badge is always shown.

What sizes does the widget support?

Any: the iframe fills its container. In narrow containers the interface automatically switches to the compact layout.