Widget Guide

Web widget integration guide for Supernal TTS

🎨 Supernal TTS Widget Guide

:::warning Development Status The Supernal TTS Widget is currently under active development. APIs, features, and integration methods may change. Please test thoroughly before using in production. :::

The Supernal TTS Widget provides an easy way to add text-to-speech functionality to any website with minimal setup.

🚀 Quick Start

1. Include the Widget

Add the widget script to your HTML:

<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
</head>
<body>
    <h1>Welcome to my blog</h1>
    <p>This content can be read aloud!</p>
    
    <!-- Supernal TTS Widget -->
    <script src="https://tts.supernal.ai/widget.js"></script>
    <script>
        SupernalTTS.init({
            apiUrl: 'https://tts.supernal.ai',
            provider: 'mock' // Start with mock for testing
        });
    </script>
</body>
</html>

2. Test the Widget

Open your page and you should see:

  • A floating audio button
  • Click to hear the page content
  • Automatic text extraction and playback

⚙️ Configuration Options

SupernalTTS.init({
    // Required
    apiUrl: 'https://tts.supernal.ai',
    
    // Provider settings
    provider: 'openai',           // openai, cartesia, azure, mock
    voice: 'fable',               // Provider-specific voice
    speed: 1.0,                   // 0.25 to 4.0
    
    // Widget appearance
    position: 'bottom-right',     // bottom-right, bottom-left, top-right, top-left
    theme: 'light',               // light, dark, auto
    size: 'medium',               // small, medium, large
    
    // Content selection
    selector: 'article, .content', // CSS selector for content
    excludeSelector: '.no-audio', // Elements to exclude
    
    // Behavior
    autoPlay: false,              // Start playing immediately
    showProgress: true,           // Show playback progress
    enableKeyboard: true,         // Keyboard shortcuts (space to play/pause)
    
    // Caching
    enableCache: true,            // Use cached audio when available
    
    // Events
    onPlay: () => console.log('Started playing'),
    onPause: () => console.log('Paused'),
    onEnd: () => console.log('Finished playing'),
    onError: (error) => console.error('Error:', error)
});

🎯 Content Selection

Automatic Detection

By default, the widget looks for common content containers:

// Default selectors (in priority order)
[
    'article',
    '.content',
    '.post-content',
    '.entry-content',
    'main',
    'body'
]

Custom Selection

Specify exactly what content to read:

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    selector: '.blog-post-content',
    excludeSelector: '.sidebar, .comments, .ads'
});

Manual Content

Provide content directly:

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    content: 'This specific text will be read aloud.'
});

🎨 Styling and Themes

Built-in Themes

// Light theme (default)
SupernalTTS.init({
    theme: 'light'
});

// Dark theme
SupernalTTS.init({
    theme: 'dark'
});

// Auto theme (matches system preference)
SupernalTTS.init({
    theme: 'auto'
});

Custom Styling

Override widget styles with CSS:

/* Custom button styling */
.supernal-tts-button {
    background: #your-brand-color !important;
    border-radius: 50% !important;
}

/* Custom player styling */
.supernal-tts-player {
    background: rgba(0, 0, 0, 0.9) !important;
    backdrop-filter: blur(10px) !important;
}

/* Hide widget on mobile */
@media (max-width: 768px) {
    .supernal-tts-widget {
        display: none !important;
    }
}

🎮 Interactive Controls

Player Controls

The widget provides a full audio player:

  • Play/Pause - Space bar or click button
  • Progress Bar - Click to seek to position
  • Speed Control - Adjust playback speed
  • Volume Control - Adjust audio volume
  • Close - Hide the player

Keyboard Shortcuts

KeyAction
SpacePlay/Pause
Rewind 10 seconds
Forward 10 seconds
Increase speed
Decrease speed
EscClose player

📱 Mobile Optimization

The widget is fully responsive and mobile-friendly:

SupernalTTS.init({
    // Mobile-specific settings
    position: 'bottom-center',    // Better for mobile
    size: 'large',                // Easier to tap
    showProgress: false,          // Less clutter
    
    // Mobile detection
    mobileOnly: false,            // Show on mobile only
    desktopOnly: false,           // Show on desktop only
});

🔧 Advanced Usage

Multiple Widgets

Create multiple widgets for different content areas:

// Main content widget
const mainWidget = SupernalTTS.create({
    apiUrl: 'https://tts.supernal.ai',
    selector: '.main-content',
    position: 'bottom-right'
});

// Sidebar widget
const sidebarWidget = SupernalTTS.create({
    apiUrl: 'https://tts.supernal.ai',
    selector: '.sidebar-content',
    position: 'bottom-left',
    voice: 'nova'
});

Dynamic Content

Update widget content dynamically:

const widget = SupernalTTS.create({
    apiUrl: 'https://tts.supernal.ai'
});

// Update content when page changes
function updateContent(newContent) {
    widget.updateContent(newContent);
}

// Refresh content from DOM
function refreshContent() {
    widget.refresh();
}

Event Handling

Listen to widget events:

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    
    onReady: () => {
        console.log('Widget is ready');
    },
    
    onContentLoaded: (text) => {
        console.log('Content loaded:', text.length, 'characters');
    },
    
    onAudioGenerated: (audioUrl, metadata) => {
        console.log('Audio generated:', audioUrl);
        console.log('Duration:', metadata.duration, 'seconds');
    },
    
    onPlay: (position) => {
        console.log('Playing from position:', position);
    },
    
    onProgress: (position, duration) => {
        console.log('Progress:', position, '/', duration);
    },
    
    onEnd: () => {
        console.log('Playback finished');
    },
    
    onError: (error) => {
        console.error('Widget error:', error);
    }
});

🔒 Security Considerations

CORS Configuration

Ensure your API allows requests from your domain:

# In your .env file
ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com

Content Security Policy

If using CSP, allow the widget resources:

<meta http-equiv="Content-Security-Policy" 
      content="script-src 'self' https://tts.supernal.ai; 
               media-src 'self' https://tts.supernal.ai;">

API Key Security

Never expose API keys in client-side code:

// ❌ DON'T DO THIS
SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    apiKey: 'sk-tts-your-secret-key' // Exposed to users!
});

// ✅ DO THIS - Use server-side proxy
SupernalTTS.init({
    apiUrl: 'https://yourdomain.com/api/tts-proxy' // Your secure endpoint
});

🚀 Production Deployment

CDN Hosting

Host the widget on a CDN for better performance:

<script src="https://cdn.yourdomain.com/supernal-tts-widget.min.js"></script>

Lazy Loading

Load the widget only when needed:

// Load widget when user interacts
document.addEventListener('click', loadWidget, { once: true });

function loadWidget() {
    const script = document.createElement('script');
    script.src = 'https://tts.supernal.ai/widget.js';
    script.onload = () => {
        SupernalTTS.init({
            apiUrl: 'https://tts.supernal.ai'
        });
    };
    document.head.appendChild(script);
}

Performance Optimization

SupernalTTS.init({
    // Optimize for performance
    enableCache: true,           // Use cached audio
    preload: 'metadata',         // Preload audio metadata only
    quality: 'standard',         // Use standard quality for faster generation
    
    // Reduce network requests
    batchRequests: true,         // Batch multiple requests
    debounceMs: 300,            // Debounce content changes
});

🐛 Troubleshooting

Common Issues

Widget not appearing:

// Check console for errors
console.log('SupernalTTS available:', typeof SupernalTTS !== 'undefined');

// Verify API connection
fetch('https://tts.supernal.ai/health')
    .then(r => r.json())
    .then(console.log);

Audio not playing:

// Check browser audio permissions
navigator.permissions.query({name: 'microphone'})
    .then(result => console.log('Audio permission:', result.state));

// Test with mock provider
SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    provider: 'mock' // Should always work
});

Content not detected:

// Debug content selection
SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    debug: true, // Enable debug logging
    onContentLoaded: (text) => {
        console.log('Detected content:', text);
    }
});

Debug Mode

Enable detailed logging:

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    debug: true,
    logLevel: 'verbose' // verbose, info, warn, error
});

📚 Examples

Blog Integration

<!DOCTYPE html>
<html>
<head>
    <title>My Blog</title>
</head>
<body>
    <article class="blog-post">
        <h1>My Blog Post Title</h1>
        <div class="post-content">
            <p>This is the content that will be read aloud...</p>
        </div>
        <aside class="sidebar no-audio">
            This sidebar content will be excluded.
        </aside>
    </article>
    
    <script src="https://tts.supernal.ai/widget.js"></script>
    <script>
        SupernalTTS.init({
            apiUrl: 'https://tts.supernal.ai',
            selector: '.post-content',
            excludeSelector: '.no-audio',
            provider: 'openai',
            voice: 'fable'
        });
    </script>
</body>
</html>

E-learning Platform

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    selector: '.lesson-content',
    provider: 'cartesia', // Low latency for interactive content
    voice: 'confident-british-man',
    speed: 0.9, // Slightly slower for learning
    
    onEnd: () => {
        // Mark lesson as completed
        markLessonComplete();
    }
});

Accessibility Enhancement

SupernalTTS.init({
    apiUrl: 'https://tts.supernal.ai',
    
    // Accessibility features
    enableKeyboard: true,
    showProgress: true,
    highContrast: true,
    
    // Screen reader friendly
    ariaLabels: {
        playButton: 'Play article audio',
        pauseButton: 'Pause article audio',
        progressBar: 'Audio playback progress'
    }
});

For more examples and advanced configurations, see the Examples section.