Vidtreo

Web Component

Use VIDTREO with any framework or vanilla HTML using the custom element.

Web Component

The @vidtreo/recorder-wc package provides a framework-agnostic Web Component that works with Vue, Angular, Svelte, or plain HTML.

Installation

Via npm

npm install @vidtreo/recorder-wc

Via CDN (No Build Required)

<script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>

Basic Usage

HTML

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>
</head>
<body>
  <vidtreo-recorder
    api-key="your-api-key"
    lang="en"
  ></vidtreo-recorder>

  <script>
    const recorder = document.querySelector('vidtreo-recorder');

    recorder.addEventListener('upload-complete', (event) => {
      console.log('Video URL:', event.detail.uploadUrl);
      console.log('Recording ID:', event.detail.recordingId);
    });

    recorder.addEventListener('error', (event) => {
      console.error('Error:', event.detail);
    });
  </script>
</body>
</html>

Vue.js

<template>
  <vidtreo-recorder
    :api-key="apiKey"
    lang="en"
    @upload-complete="handleUploadComplete"
    @error="handleError"
  />
</template>

<script setup>
import '@vidtreo/recorder-wc';

const apiKey = import.meta.env.VITE_VIDTREO_API_KEY;

function handleUploadComplete(event) {
  console.log('Video URL:', event.detail.uploadUrl);
}

function handleError(event) {
  console.error('Error:', event.detail);
}
</script>

Angular

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import '@vidtreo/recorder-wc';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  // ...
})
export class AppModule {}
<!-- recorder.component.html -->
<vidtreo-recorder
  [attr.api-key]="apiKey"
  lang="en"
  (upload-complete)="onUploadComplete($event)"
  (error)="onError($event)"
></vidtreo-recorder>

Svelte

<script>
  import '@vidtreo/recorder-wc';

  const apiKey = import.meta.env.VITE_VIDTREO_API_KEY;

  function handleUploadComplete(event) {
    console.log('Video URL:', event.detail.uploadUrl);
  }

  function handleError(event) {
    console.error('Error:', event.detail);
  }
</script>

<vidtreo-recorder
  api-key={apiKey}
  lang="en"
  on:upload-complete={handleUploadComplete}
  on:error={handleError}
/>

Attributes

All attributes use kebab-case (HTML convention):

AttributeTypeDefaultDescription
api-keystringrequiredYour VIDTREO API key
backend-urlstringhttps://core.vidtreo.comAPI endpoint
countdown-durationnumber3000Pre-recording countdown (ms)
max-recording-timenumberundefinedMax duration (ms)
user-metadatastringundefinedJSON string of metadata
enable-source-switchingbooleantrueCamera/screen toggle
enable-mutebooleantrueMute button
enable-pausebooleantruePause/resume
enable-device-changebooleantrueDevice selection
mobile-modestring"overlay"Mobile mode: "overlay", "embed", "native"
langstring"en"UI language
textsstringundefinedJSON string of custom texts

Setting Attributes Dynamically

const recorder = document.querySelector('vidtreo-recorder');

// Simple attributes
recorder.setAttribute('lang', 'es');
recorder.setAttribute('max-recording-time', '120000');

// JSON attributes (metadata and texts)
recorder.setAttribute('user-metadata', JSON.stringify({
  userId: 'user-123',
  sessionId: 'session-456'
}));

recorder.setAttribute('texts', JSON.stringify({
  record: 'Start Capture',
  stop: 'End Capture'
}));

Events

Listen for events using addEventListener or framework-specific syntax:

EventDetailDescription
recording-start{}Recording started
recording-stop{}Recording stopped
upload-progress{ progress: number }Upload progress (0-1)
upload-complete{ uploadUrl, recordingId }Upload finished
upload-error{ error: Error }Upload failed
error{ error: Error }Any error

Event Examples

const recorder = document.querySelector('vidtreo-recorder');

recorder.addEventListener('recording-start', () => {
  console.log('Recording started');
});

recorder.addEventListener('recording-stop', () => {
  console.log('Recording stopped');
});

recorder.addEventListener('upload-progress', (e) => {
  const percent = Math.round(e.detail.progress * 100);
  console.log(`Upload progress: ${percent}%`);
});

recorder.addEventListener('upload-complete', (e) => {
  console.log('Video URL:', e.detail.uploadUrl);
  console.log('Recording ID:', e.detail.recordingId);
});

recorder.addEventListener('error', (e) => {
  console.error('Error:', e.detail.error);
});

Methods

Control the recorder programmatically:

const recorder = document.querySelector('vidtreo-recorder');

// Start camera preview
await recorder.startCamera();

// Recording controls
await recorder.startRecording();
await recorder.stopRecording();
recorder.pauseRecording();
recorder.resumeRecording();

// Source controls
await recorder.toggleSource();  // Switch camera/screen
recorder.toggleMute();

// Device controls
await recorder.handleCameraChange('device-id');
await recorder.handleMicChange('device-id');

// Settings panel
recorder.toggleSettings();

// Video playback (after recording)
recorder.playVideo();
recorder.downloadVideo();

// Process video (transcoding)
await recorder.processVideo();

Styling

The Web Component renders in the light DOM (no Shadow DOM), so its markup can be styled with regular CSS. Style the container:

vidtreo-recorder {
  /* Container dimensions */
  width: 100%;
  max-width: 640px;
  height: 480px;

  /* Container styling */
  display: block;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

CSS Custom Properties (Coming Soon)

vidtreo-recorder {
  --vidtreo-primary-color: #3b82f6;
  --vidtreo-background: #1f2937;
  --vidtreo-text-color: #ffffff;
  --vidtreo-border-radius: 8px;
}

Internationalization

Built-in Languages

<!-- English (default) -->
<vidtreo-recorder api-key="..." lang="en"></vidtreo-recorder>

<!-- Spanish -->
<vidtreo-recorder api-key="..." lang="es"></vidtreo-recorder>

<!-- Portuguese -->
<vidtreo-recorder api-key="..." lang="pt"></vidtreo-recorder>

Custom Texts

<vidtreo-recorder
  api-key="..."
  lang="en"
  texts='{"record": "Start Capture", "stop": "End Capture", "uploading": "Sending..."}'
></vidtreo-recorder>

Available Text Keys

KeyDefault (English)
titleRecord Video
subtitleClick record to start
initializingCameraInitializing camera...
grantPermissionsPlease grant camera permissions
retryCameraRetry
switchingDeviceSwitching device...
recordingStartsInRecording starts in
switchingSourceSwitching source...
recREC
settingsSettings
recordRecord
stopStop
pausePause
resumeResume
muteMute
unmuteUnmute
switchSourceSwitch Source
cameraCamera
microphoneMicrophone
processVideoProcess Video
processingProcessing...
uploadingUploading...
switchingCameraSwitching camera...
switchingMicrophoneSwitching microphone...
failedToStartCameraFailed to start camera

Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Video Recorder</title>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>
  <style>
    body {
      font-family: system-ui, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 2rem;
    }

    vidtreo-recorder {
      width: 100%;
      max-width: 640px;
      height: 480px;
      display: block;
      margin: 0 auto;
      border-radius: 12px;
      overflow: hidden;
    }

    .result {
      margin-top: 2rem;
      text-align: center;
    }

    .result video {
      max-width: 100%;
      border-radius: 8px;
    }

    .progress {
      margin-top: 1rem;
      text-align: center;
    }

    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <h1>Record Your Video</h1>

  <vidtreo-recorder
    id="recorder"
    api-key="your-api-key"
    enable-source-switching="true"
    enable-mute="true"
    enable-pause="true"
    enable-device-change="true"
    max-recording-time="120000"
    countdown-duration="3000"
    lang="en"
  ></vidtreo-recorder>

  <div id="progress" class="progress hidden">
    <p>Uploading: <span id="percent">0</span>%</p>
  </div>

  <div id="result" class="result hidden">
    <h2>Recording Complete!</h2>
    <video id="video" controls></video>
    <p><a id="link" href="#" target="_blank">Open in new tab</a></p>
  </div>

  <script>
    const recorder = document.getElementById('recorder');
    const progress = document.getElementById('progress');
    const percent = document.getElementById('percent');
    const result = document.getElementById('result');
    const video = document.getElementById('video');
    const link = document.getElementById('link');

    recorder.addEventListener('recording-start', () => {
      result.classList.add('hidden');
    });

    recorder.addEventListener('upload-progress', (e) => {
      progress.classList.remove('hidden');
      percent.textContent = Math.round(e.detail.progress * 100);
    });

    recorder.addEventListener('upload-complete', (e) => {
      progress.classList.add('hidden');
      result.classList.remove('hidden');
      video.src = e.detail.uploadUrl;
      link.href = e.detail.uploadUrl;
    });

    recorder.addEventListener('error', (e) => {
      progress.classList.add('hidden');
      alert('Error: ' + e.detail.error.message);
    });
  </script>
</body>
</html>

TypeScript Support

For TypeScript projects, add type declarations:

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'vidtreo-recorder': React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement> & {
          'api-key'?: string;
          'backend-url'?: string;
          'countdown-duration'?: string;
          'max-recording-time'?: string;
          'user-metadata'?: string;
          'enable-source-switching'?: string;
          'enable-mute'?: string;
          'enable-pause'?: string;
          'enable-device-change'?: string;
          'lang'?: string;
          'texts'?: string;
        },
        HTMLElement
      >;
    }
  }
}

Next Steps

On this page