Vidtreo

Advanced Usage

Advanced patterns for error handling, offline support, and more.

Advanced Usage

Advanced patterns and best practices for production applications.

Error Handling

import { VidtreoRecorder } from '@vidtreo/recorder-react';
import { useState } from 'react';

function RobustRecorder() {
  const [error, setError] = useState<string | null>(null);

  const handleError = (err: Error) => {
    // Handle specific errors
    if (err.message.includes('NotAllowedError')) {
      setError('Camera access denied. Please allow permissions.');
    } else if (err.message.includes('NotFoundError')) {
      setError('No camera found. Please connect a camera.');
    } else if (err.message.includes('NotSupportedError')) {
      setError('Your browser does not support video recording.');
    } else if (err.message.includes('Upload failed')) {
      setError('Upload failed. Please check your connection.');
    } else {
      setError(err.message);
    }
  };

  return (
    <div>
      <VidtreoRecorder
        apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
        onError={handleError}
        onUploadError={handleError}
      />

      {error && (
        <div className="error-banner">
          <p>{error}</p>
          <button onClick={() => setError(null)}>Dismiss</button>
        </div>
      )}
    </div>
  );
}

Retry Logic

function RecorderWithRetry() {
  const [retryCount, setRetryCount] = useState(0);
  const [lastBlob, setLastBlob] = useState<Blob | null>(null);

  const retryUpload = async () => {
    if (!lastBlob) return;

    try {
      // Manual upload using core SDK
      const { UploadService } = await import('@vidtreo/recorder');
      const service = new UploadService({
        apiKey: import.meta.env.VITE_VIDTREO_API_KEY
      });
      const result = await service.upload(lastBlob);
      console.log('Retry successful:', result);
      setLastBlob(null);
    } catch (err) {
      setRetryCount(c => c + 1);
    }
  };

  return (
    <VidtreoRecorder
      apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
      onUploadError={(err) => {
        // Store blob for retry
        console.error('Upload failed, blob saved for retry');
      }}
    />
  );
}

Offline Support

The SDK automatically queues recordings when offline:

function OfflineAwareRecorder() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return (
    <div>
      {!isOnline && (
        <div className="offline-banner">
          You are offline. Recordings will upload when connected.
        </div>
      )}

      <VidtreoRecorder
        apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
        onUploadComplete={(result) => {
          console.log('Upload complete:', result.uploadUrl);
        }}
      />
    </div>
  );
}

Recording Limits

Enforce recording constraints:

function LimitedRecorder() {
  const [recordingCount, setRecordingCount] = useState(0);
  const MAX_RECORDINGS = 5;

  if (recordingCount >= MAX_RECORDINGS) {
    return <p>You have reached the recording limit.</p>;
  }

  return (
    <VidtreoRecorder
      apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
      maxRecordingTime={60000} // 1 minute max
      onUploadComplete={(result) => {
        setRecordingCount(c => c + 1);
        console.log(`Recording ${recordingCount + 1}/${MAX_RECORDINGS}`);
      }}
    />
  );
}

Analytics Integration

function AnalyticsRecorder() {
  const trackEvent = (event: string, data?: object) => {
    // Send to your analytics service
    analytics.track(event, data);
  };

  return (
    <VidtreoRecorder
      apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
      onRecordingStart={() => {
        trackEvent('recording_started');
      }}
      onRecordingStop={() => {
        trackEvent('recording_stopped');
      }}
      onUploadProgress={(progress) => {
        if (progress === 0.5) {
          trackEvent('upload_halfway');
        }
      }}
      onUploadComplete={(result) => {
        trackEvent('recording_complete', {
          recordingId: result.recordingId,
          url: result.uploadUrl
        });
      }}
      onError={(error) => {
        trackEvent('recording_error', {
          message: error.message
        });
      }}
    />
  );
}

Form Integration

Embed recorder in a form:

function FeedbackForm() {
  const [videoUrl, setVideoUrl] = useState<string | null>(null);
  const [feedback, setFeedback] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    await submitFeedback({
      text: feedback,
      videoUrl: videoUrl
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <textarea
        value={feedback}
        onChange={(e) => setFeedback(e.target.value)}
        placeholder="Describe your feedback..."
      />

      <VidtreoRecorder
        apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
        maxRecordingTime={120000}
        userMetadata={{ formType: 'feedback' }}
        onUploadComplete={(result) => {
          setVideoUrl(result.uploadUrl);
        }}
      />

      {videoUrl && <p>Video attached</p>}

      <button type="submit">Submit Feedback</button>
    </form>
  );
}

Browser Support Detection

function BrowserAwareRecorder() {
  const [isSupported, setIsSupported] = useState(true);

  useEffect(() => {
    // Check for WebCodecs support
    const supported =
      'VideoEncoder' in window &&
      'AudioEncoder' in window &&
      navigator.mediaDevices?.getUserMedia;

    setIsSupported(!!supported);
  }, []);

  if (!isSupported) {
    return (
      <div className="unsupported">
        <h3>Browser Not Supported</h3>
        <p>Please use Chrome, Edge, or Safari 16.4+</p>
      </div>
    );
  }

  return (
    <VidtreoRecorder
      apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
    />
  );
}

See Also

On this page