> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cekura.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview Embedding (Deprecated)

> Learn how to embed Cekura agent overview in your application using our embed widget. For token management details, see our [Token Generation](/embed/generate-token) and [Token Refresh](/embed/refreshing-expired-token) guides.

export const CopyPageButton = () => {
  if (typeof window !== 'undefined') {
    setTimeout(function () {
      if (document.getElementById('ck-tools')) return;
      var anchor = document.getElementById('content-area') || document.querySelector('.mdx-content');
      if (!anchor) return;
      if (!document.getElementById('ck-style')) {
        var s = document.createElement('style');
        s.id = 'ck-style';
        s.textContent = '#ck-tools{position:absolute;top:6px;right:0;z-index:100;font-family:inherit;}' + '.ck-row{display:inline-flex;align-items:stretch;border:1px solid rgba(0,0,0,0.15);border-radius:8px;overflow:hidden;background:#fff;}' + ':root.dark .ck-row{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12);}' + '.ck-btn{padding:5px 12px;border:none;background:none;cursor:pointer;font-size:13px;font-weight:500;font-family:inherit;color:#374151;}' + ':root.dark .ck-btn{color:#d1d5db;}' + '.ck-btn:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-btn:hover{background:rgba(255,255,255,0.06);}' + '.ck-chevron{padding:5px 8px;border:none;background:none;cursor:pointer;font-size:14px;font-family:inherit;color:#374151;}' + ':root.dark .ck-chevron{color:#d1d5db;}' + '.ck-chevron:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-chevron:hover{background:rgba(255,255,255,0.06);}' + '.ck-divider{width:1px;background:rgba(0,0,0,0.12);flex-shrink:0;}' + ':root.dark .ck-divider{background:rgba(255,255,255,0.12);}' + '.ck-dd{position:absolute;top:calc(100% + 4px);right:0;min-width:180px;background:#fff;border:1px solid rgba(0,0,0,0.12);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.1);padding:4px;display:none;z-index:200;}' + ':root.dark .ck-dd{background:#1f2937;border-color:rgba(255,255,255,0.1);box-shadow:0 4px 16px rgba(0,0,0,0.35);}' + '.ck-item{display:block;width:100%;padding:7px 12px;border:none;background:none;border-radius:6px;cursor:pointer;font-size:13px;font-family:inherit;text-align:left;color:#374151;}' + ':root.dark .ck-item{color:#d1d5db;}' + '.ck-item:hover{background:rgba(0,0,0,0.05);}' + ':root.dark .ck-item:hover{background:rgba(255,255,255,0.07);}';
        document.head.appendChild(s);
      }
      var wrap = document.createElement('div');
      wrap.id = 'ck-tools';
      var row = document.createElement('div');
      row.className = 'ck-row';
      var mainBtn = document.createElement('button');
      mainBtn.className = 'ck-btn';
      mainBtn.textContent = 'Copy page';
      var divider = document.createElement('span');
      divider.className = 'ck-divider';
      var chevron = document.createElement('button');
      chevron.className = 'ck-chevron';
      chevron.textContent = '▾';
      var dd = document.createElement('div');
      dd.className = 'ck-dd';
      function closeDD() {
        dd.style.display = 'none';
      }
      function openDD() {
        dd.style.display = 'block';
      }
      chevron.onclick = function (e) {
        e.stopPropagation();
        if (dd.style.display === 'block') {
          closeDD();
        } else {
          openDD();
        }
      };
      document.addEventListener('click', function (e) {
        if (!e.target.closest('#ck-tools')) {
          closeDD();
        }
      });
      document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') {
          closeDD();
        }
      });
      function makeItem(label, fn) {
        var b = document.createElement('button');
        b.className = 'ck-item';
        b.textContent = label;
        b.onclick = function () {
          fn();
          closeDD();
        };
        return b;
      }
      function getMarkdown() {
        var walk = function (node) {
          if (!node) return '';
          if (node.nodeType === 3) return node.textContent || '';
          if (node.nodeType !== 1) return '';
          var tag = node.tagName.toLowerCase();
          var skip = ['script', 'style', 'svg', 'noscript', 'button', 'iframe'];
          if (skip.indexOf(tag) !== -1) return '';
          if (node.id === 'ck-tools') return '';
          var ch = Array.from(node.childNodes).map(walk).join('');
          if (tag === 'h1') return '\n# ' + ch.trim() + '\n\n';
          if (tag === 'h2') return '\n## ' + ch.trim() + '\n\n';
          if (tag === 'h3') return '\n### ' + ch.trim() + '\n\n';
          if (tag === 'p') return '\n' + ch.trim() + '\n\n';
          if (tag === 'pre') return '\n```\n' + node.textContent.trim() + '\n```\n\n';
          if (tag === 'li') return '- ' + ch.trim() + '\n';
          if (tag === 'code') return '`' + ch.trim() + '`';
          return ch;
        };
        var content = document.querySelector('.mdx-content') || document.getElementById('content-area') || document.body;
        return walk(content).replace(/\n\n\n+/g, '\n\n').trim();
      }
      function copyMd() {
        var md = getMarkdown();
        navigator.clipboard.writeText(md).then(function () {
          mainBtn.textContent = 'Copied!';
          setTimeout(function () {
            mainBtn.textContent = 'Copy page';
          }, 2000);
        });
      }
      function viewMd() {
        var md = getMarkdown();
        var safe = md.split('&').join('&amp;').split('<').join('&lt;').split('>').join('&gt;');
        var html = '<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{font-family:monospace;max-width:860px;margin:40px auto;padding:0 24px;line-height:1.7;white-space:pre-wrap;word-wrap:break-word}</style></head><body>' + safe + '</body></html>';
        window.open(URL.createObjectURL(new Blob([html], {
          type: 'text/html'
        })), '_blank');
      }
      function openClaude() {
        var prompt = 'Can you read this Cekura docs page ' + window.location.href + ' so I can ask you questions?';
        window.open('https://claude.ai/new?q=' + encodeURIComponent(prompt), '_blank');
      }
      mainBtn.onclick = copyMd;
      dd.appendChild(makeItem('Copy page', copyMd));
      dd.appendChild(makeItem('View as Markdown', viewMd));
      dd.appendChild(makeItem('Open in Claude', openClaude));
      row.appendChild(mainBtn);
      row.appendChild(divider);
      row.appendChild(chevron);
      wrap.appendChild(row);
      wrap.appendChild(dd);
      anchor.style.position = 'relative';
      anchor.insertBefore(wrap, anchor.firstChild);
    }, 50);
  }
  return null;
};

<CopyPageButton />

<Warning>
  **Deprecation Notice**

  All embedding features are being deprecated and will be removed from shortly.\
  We recommend that you do not build new integrations using this feature.

  **Recommended Alternative:** We recommend integrating Cekura into your platform via our [APIs](/api-reference). We also have an [MCP server](/mcp) to make it easier for you — simply ask Claude Code to use the Cekura MCP and get a UI quickly!

  If you have existing integrations using Overview Embedding, please plan to migrate to our APIs before the removal date.
</Warning>

## Prerequisites

* Cekura API key
* Agent ID
* Development environment for your chosen framework

## URL Structure

The embed URL follows this pattern:

```
https://dashboard.cekura.ai/embed/{agentId}/overview?token={token}&theme={theme}
```

Where:

* `{agentId}`: Your agent's unique identifier
* `{token}`: Your authentication token
* `{theme}`: Theme preference ('dark' or 'light')

## Framework Implementations

<Tabs>
  <Tab title="React">
    ```jsx theme={null}
    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;
    ```
  </Tab>

  <Tab title="Vue">
    ```vue theme={null}
    <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>

    ```
  </Tab>

  <Tab title="Angular">
    ```typescript theme={null}
    // 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));
      }
    }
    ```
  </Tab>

  <Tab title="HTML/JavaScript">
    ```javascript theme={null}
    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');

    ```
  </Tab>
</Tabs>

## Event Handling

Each framework implementation above includes handlers for these core events:

```javascript theme={null}
// Token expired event
if (event.data === 'token_expired') {
  await refreshToken(); // See /embed/refreshing-expired-token for implementation
}
```

For token management implementation details, refer to:

* [Token Generation Guide](/embed/generate-token)
* [Token Refresh Guide](/embed/refreshing-expired-token)
