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.
| Parameter | Description |
|---|---|
| data-key* | Public embed key (mk_live_…) from the dashboard. |
| data-mode | inline (default, iframe in your container) or bubble — a floating call button in the page corner; no container needed. |
| data-target | CSS selector of the container. Without it a 520px-high block is created right after the script tag. |
| data-room-name | Persistent named room: everyone with this snippet meets in the same room («support»). The key owner joins as host from the dashboard. |
| data-position | Bubble corner: bottom-right (default) or bottom-left. |
| data-label | aria-label of the bubble button (the widget doesn’t know your site’s language). |
| data-room | Existing room code (meeto.me/<code>). Without it the widget creates a room itself and reuses it within the tab. |
| data-name | Participant name prefilled in the lobby. |
| data-lang | Widget interface language (en, ru, de, …). Default — the visitor’s browser language. |
| data-accent | Accent color, hex (e.g. #27D6AA). |
| data-auto-join | Skip the lobby and join immediately (open-door rooms only; camera and mic start enabled). |
| data-base-url | Meeto 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));| Event | Payload |
|---|---|
| ready | — — the 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:
| Method | Description |
|---|---|
| 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.2import 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-ios ↗meeto-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- In the WordPress admin, open Plugins → Add New → Upload Plugin and upload the zip.
- Activate the plugin and open Settings → Meeto Widget.
- 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.