Prerequisites
- Cekura API key
- Agent ID
- Development environment for your chosen framework
URL Structure
The embed URL follows this pattern:Copy
Ask AI
https://dashboard.cekura.ai/embed/{agentId}/overview?token={token}&theme={theme}
{agentId}: Your agent’s unique identifier{token}: Your authentication token{theme}: Theme preference (‘dark’ or ‘light’)
Framework Implementations
- React
- Vue
- Angular
- HTML/JavaScript
Copy
Ask AI
import { useEffect, useState } from 'react';
const VoceraOverviewEmbed = ({ agentId, theme = 'light' }) => {
const [token, setToken] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const handleMessage = async (event) => {
// Token expired event
if (event.data === 'token_expired') {
try {
await refreshToken(); // See /embed/refreshing-expired-token for implementation
} catch (err) {
setError('Failed to refresh token');
}
}
};
const initializeToken = async () => {
try {
const newToken = await initToken(); // See /embed/generate-token for implementation
setToken(newToken);
} catch (err) {
setError('Failed to initialize token');
}
};
window.addEventListener('message', handleMessage);
initializeToken();
return () => window.removeEventListener('message', handleMessage);
}, [agentId]);
if (error) return <div className="error-message">{error}</div>;
if (!token || isLoading) return <div className="loading-state">Loading...</div>;
return (
<iframe
src={`https://dashboard.cekura.ai/embed/${agentId}/overview?token=${token}&theme=${theme}`}
className="w-full h-[950px] border-0"
allowFullScreen
loading="lazy"
title="Cekura Overview Embed"
/>
);
};
export default VoceraOverviewEmbed;
Copy
Ask AI
<template>
<div class="vocera-embed-container">
<div v-if="error" class="error-message">{{ error }}</div>
<iframe
v-else-if="token && !isLoading"
:src="embedUrl"
class="w-full h-[950px] border-0"
allowfullscreen
loading="lazy"
title="Cekura Overview Embed"
/>
<div v-else class="loading-state">Loading...</div>
</div>
</template>
<script>
export default {
name: 'VoceraOverviewEmbed',
props: {
agentId: {
type: String,
required: true
},
theme: {
type: String,
default: 'light',
validator: value => ['dark', 'light'].includes(value)
}
},
data() {
return {
token: null,
isLoading: true,
error: null
}
},
computed: {
embedUrl() {
return `https://dashboard.cekura.ai/embed/${this.agentId}/overview?token=${this.token}&theme=${this.theme}`;
}
},
methods: {
async handleMessage(event) {
if (event.data === 'token_expired') {
try {
await this.refreshToken(); // See /embed/refreshing-expired-token
} catch (err) {
this.error = 'Failed to refresh token';
}
}
},
async initializeToken() {
try {
this.token = await this.initToken(); // See /embed/generate-token
} catch (err) {
this.error = 'Failed to initialize token';
}
}
},
async mounted() {
window.addEventListener('message', this.handleMessage);
await this.initializeToken();
},
beforeUnmount() {
window.removeEventListener('message', this.handleMessage);
}
};
</script>
<style scoped>
.error-message {
color: red;
padding: 1rem;
}
.loading-state {
padding: 1rem;
text-align: center;
}
</style>
Copy
Ask AI
// vocera-overview-embed.component.ts
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
@Component({
selector: 'app-vocera-overview-embed',
template: `
<div class="vocera-embed-container">
<div *ngIf="error" class="error-message">{{ error }}</div>
<iframe
*ngIf="token && !isLoading"
[src]="embedUrl"
class="w-full h-[950px] border-0"
allowfullscreen
loading="lazy"
title="Cekura Overview Embed"
></iframe>
<div *ngIf="!token || isLoading" class="loading-state">Loading...</div>
</div>
`,
styles: [`
.error-message {
color: red;
padding: 1rem;
}
.loading-state {
padding: 1rem;
text-align: center;
}
`]
})
export class VoceraOverviewEmbedComponent implements OnInit, OnDestroy {
@Input() agentId!: string;
@Input() theme: 'dark' | 'light' = 'light';
token: string | null = null;
isLoading = true;
error: string | null = null;
constructor(private sanitizer: DomSanitizer) {}
get embedUrl(): SafeUrl {
const url = `https://dashboard.cekura.ai/embed/${this.agentId}/overview?token=${this.token}&theme=${this.theme}`;
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
async handleMessage(event: MessageEvent): Promise<void> {
if (event.data === 'token_expired') {
try {
await this.refreshToken(); // See /embed/refreshing-expired-token
} catch (err) {
this.error = 'Failed to refresh token';
}
}
}
async ngOnInit(): Promise<void> {
window.addEventListener('message', this.handleMessage.bind(this));
try {
this.token = await this.initToken(); // See /embed/generate-token
} catch (err) {
this.error = 'Failed to initialize token';
}
}
ngOnDestroy(): void {
window.removeEventListener('message', this.handleMessage.bind(this));
}
}
Copy
Ask AI
class VoceraOverviewEmbed {
constructor(containerId, agentId, theme = 'light') {
this.container = document.getElementById(containerId);
this.agentId = agentId;
this.theme = theme;
this.token = null;
this.isLoading = true;
this.init();
}
async init() {
try {
this.token = await this.initToken(); // See /embed/generate-token
this.createIframe();
window.addEventListener('message', this.handleMessage.bind(this));
} catch (err) {
this.showError('Failed to initialize token');
}
}
handleMessage(event) {
if (event.data === 'token_expired') {
this.handleTokenExpiration();
}
}
async handleTokenExpiration() {
try {
await this.refreshToken(); // See /embed/refreshing-expired-token
this.updateIframe();
} catch (err) {
this.showError('Failed to refresh token');
}
}
createIframe() {
const iframe = document.createElement('iframe');
iframe.width = '100%';
iframe.height = '950';
iframe.style.border = '0';
iframe.allowFullscreen = true;
iframe.loading = 'lazy';
iframe.title = 'Cekura Overview Embed';
this.iframe = iframe;
this.updateIframe();
this.container.appendChild(iframe);
}
updateIframe() {
if (this.iframe && this.token) {
this.iframe.src = `https://dashboard.cekura.ai/embed/${this.agentId}/overview?token=${this.token}&theme=${this.theme}`;
}
}
showError(message) {
const errorDiv = document.createElement('div');
errorDiv.className = 'error-message';
errorDiv.style.color = 'red';
errorDiv.style.padding = '1rem';
errorDiv.textContent = message;
this.container.innerHTML = '';
this.container.appendChild(errorDiv);
}
hideLoading() {
const loadingElement = this.container.querySelector('.loading-state');
if (loadingElement) {
loadingElement.remove();
}
}
}
// Usage examples
const overviewEmbed = new VoceraOverviewEmbed('vocera-overview-embed', 'YOUR_AGENT_ID', 'dark');
const lightOverviewEmbed = new VoceraOverviewEmbed('vocera-overview-embed', 'YOUR_AGENT_ID', 'light');
Event Handling
Each framework implementation above includes handlers for these core events:Copy
Ask AI
// Token expired event
if (event.data === 'token_expired') {
await refreshToken(); // See /embed/refreshing-expired-token for implementation
}