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-wcVia 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):
| Attribute | Type | Default | Description |
|---|---|---|---|
api-key | string | required | Your VIDTREO API key |
backend-url | string | https://core.vidtreo.com | API endpoint |
countdown-duration | number | 3000 | Pre-recording countdown (ms) |
max-recording-time | number | undefined | Max duration (ms) |
user-metadata | string | undefined | JSON string of metadata |
enable-source-switching | boolean | true | Camera/screen toggle |
enable-mute | boolean | true | Mute button |
enable-pause | boolean | true | Pause/resume |
enable-device-change | boolean | true | Device selection |
mobile-mode | string | "overlay" | Mobile mode: "overlay", "embed", "native" |
lang | string | "en" | UI language |
texts | string | undefined | JSON 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:
| Event | Detail | Description |
|---|---|---|
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
| Key | Default (English) |
|---|---|
title | Record Video |
subtitle | Click record to start |
initializingCamera | Initializing camera... |
grantPermissions | Please grant camera permissions |
retryCamera | Retry |
switchingDevice | Switching device... |
recordingStartsIn | Recording starts in |
switchingSource | Switching source... |
rec | REC |
settings | Settings |
record | Record |
stop | Stop |
pause | Pause |
resume | Resume |
mute | Mute |
unmute | Unmute |
switchSource | Switch Source |
camera | Camera |
microphone | Microphone |
processVideo | Process Video |
processing | Processing... |
uploading | Uploading... |
switchingCamera | Switching camera... |
switchingMicrophone | Switching microphone... |
failedToStartCamera | Failed 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
- Configuration Options — All settings
- Callbacks Reference — Event handling
- Examples — More examples