@xcall/web
v1.1.0
Published
xCall SDK — embed video calls in any website
Readme
@xcall/web
Embed video calls in any website with a single JavaScript class.
Installation
npm install @xcall/webHow it works
- Your backend generates a JWT token using the xCall API
- You pass that token to the SDK
- The SDK mounts a secure video call inside any HTML element
The token carries all configuration: room, user, branding, permissions. Your secret keys never reach the frontend.
Usage
React
import { useEffect, useRef } from "react";
import { XCall } from "@xcall/sdk";
export function VideoCall({ token }: { token: string }) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!containerRef.current) return;
const call = new XCall({
container: containerRef.current,
token,
});
call.on("joined", ({ roomId }) => console.log("joined", roomId));
call.on("left", ({ roomId }) => console.log("left", roomId));
call.on("error", ({ message }) => console.error(message));
return () => call.destroy();
}, [token]);
return <div ref={containerRef} style={{ width: "100%", height: "600px" }} />;
}Vue
<template>
<div ref="callContainer" style="width:100%;height:600px" />
</template>
<script setup>
import { XCall } from "@xcall/sdk";
import { ref, onMounted, onUnmounted } from "vue";
const props = defineProps(["token"]);
const callContainer = ref(null);
let call;
onMounted(() => {
call = new XCall({ container: callContainer.value, token: props.token });
call.on("left", () => console.log("left"));
});
onUnmounted(() => call?.destroy());
</script>Angular
import {
Component,
ElementRef,
ViewChild,
Input,
OnDestroy,
AfterViewInit,
} from "@angular/core";
import { XCall } from "@xcall/sdk";
@Component({
selector: "app-call",
template: '<div #container style="width:100%;height:600px"></div>',
})
export class CallComponent implements AfterViewInit, OnDestroy {
@ViewChild("container") container!: ElementRef;
@Input() token!: string;
private call!: XCall;
ngAfterViewInit() {
this.call = new XCall({
container: this.container.nativeElement,
token: this.token,
});
this.call.on("left", () => console.log("left"));
}
ngOnDestroy() {
this.call?.destroy();
}
}HTML / CDN
<div id="call" style="width:100%;height:600px"></div>
<script src="https://cdn.jsdelivr.net/npm/@xcall/sdk/dist/xcall.min.js"></script>
<script>
const call = new XCallSDK.XCall({
container: "#call",
token: "YOUR_TOKEN_HERE",
});
call.on("left", () => console.log("left"));
</script>API
new XCall(options)
| Option | Type | Required | Description |
| ------------- | ----------------------- | -------- | ------------------------------------------------------------ |
| container | HTMLElement \| string | ✅ | Element or CSS selector where the call will mount |
| token | string | ✅ | JWT token generated by your backend |
| roomUrl | string | — | Custom xCall-room URL (default: https://room.xcall.com.br) |
| iframeStyle | object | — | Extra CSS styles applied to the iframe |
Events
call.on('ready', () => void)
call.on('joined', ({ roomId, userId }) => void)
call.on('left', ({ roomId, reason? }) => void)
call.on('participant_joined',({ userId, displayName? }) => void)
call.on('participant_left', ({ userId }) => void)
call.on('error', ({ code, message }) => void)Methods
call.muteAudio(true); // mute / unmute microphone
call.muteVideo(false); // mute / unmute camera
call.leave(); // end the call programmatically
call.destroy(); // remove iframe and listeners (use on component unmount)Token generation
Tokens must be generated server-side. Never expose your API secret on the frontend.
// Example: Node.js backend
const res = await fetch("https://api.xcall.com.br/session", {
method: "POST",
headers: { "x-api-key": process.env.XCALL_SECRET },
body: JSON.stringify({ room: "my-room", user: { display_name: "John" } }),
});
const { token } = await res.json();License
MIT
