- Added engine selection buttons (Kokoro vs Piper) in VoiceAssignmentSection - Implemented getEngines(), setEngine(), and getVoices() API client functions - Engine selector dynamically loads available voices for selected engine - Added visual feedback for active engine with descriptions - Piper engine shows pitch control capability notice - Voice dropdowns update automatically when switching engines - Audio cache clears when switching engines for clean state Users can now easily switch between Kokoro (high quality) and Piper (fast with pitch control) directly from the UI.
Text to Audiobook Frontend
React TypeScript single-page application for converting text to multi-voice audiobooks.
Overview
The frontend provides an intuitive interface for:
- Text input with role marker support
- Automatic role detection
- Voice assignment per role
- Language and speed configuration
- Audio playback and download
Prerequisites
- Node.js 20.19+ or 22.12+
- npm or yarn
- Backend service running (see Backend README)
Installation
# Install dependencies
npm install
# Create environment file
cp .env.example .env
Configuration
Edit .env to configure the backend URL:
VITE_API_BASE_URL=http://localhost:8000
For production:
VITE_API_BASE_URL=https://your-backend-domain.com
Development
Start Development Server
npm run dev
The application will be available at http://localhost:5173
Development Features
- Hot Module Replacement (HMR)
- Fast refresh for React components
- TypeScript type checking
- ESLint integration
Development Commands
# Start dev server
npm run dev
# Type check
npm run type-check
# Lint code
npm run lint
# Format code
npm run format
Production Build
Build for Production
npm run build
Built files will be in dist/ directory.
Preview Production Build
npm run preview
Preview server runs on http://localhost:4173
Build Optimization
The production build includes:
- Code minification
- Tree shaking
- Asset optimization
- CSS purging (Tailwind)
- Source maps (optional)
Project Structure
frontend/
├── src/
│ ├── api/
│ │ └── tts.ts # API client & TypeScript interfaces
│ ├── components/
│ │ ├── TextInputSection.tsx # Text input component
│ │ ├── VoiceAssignmentSection.tsx # Voice assignment UI
│ │ └── AudioPlayerSection.tsx # Audio playback component
│ ├── App.tsx # Main application & state management
│ ├── App.css # Application styles
│ ├── main.tsx # Application entry point
│ └── index.css # Global styles (Tailwind)
├── public/
│ └── vite.svg # Public assets
├── index.html # HTML template
├── package.json # Dependencies & scripts
├── tsconfig.json # TypeScript configuration
├── vite.config.ts # Vite configuration
├── tailwind.config.js # Tailwind CSS configuration
├── postcss.config.js # PostCSS configuration
├── eslint.config.js # ESLint configuration
├── .env.example # Environment template
└── README.md # This file
Components
App Component (App.tsx)
Main application container managing workflow state.
State:
- Text input
- Detected roles
- Voice assignments
- Language selection
- Speed setting
- Audio URL
- Loading states
- Error handling
Phases:
- Input - Text entry
- Assignment - Voice selection
- Generated - Audio playback
TextInputSection Component
Text input interface with validation.
Features:
- Large multiline textarea
- Character count (optional)
- Validation for empty text
- "Next: Assign voices" button
- Loading state support
VoiceAssignmentSection Component
Voice assignment and configuration interface.
Features:
- Role list with voice dropdowns
- Language selector (American English, British English, French, Japanese)
- Speed slider (0.5x - 1.5x)
- "Generate Audiobook" button
- Validation (all roles must have voices)
AudioPlayerSection Component
Audio playback and download interface.
Features:
- HTML5 audio player with controls
- Download button
- Blob URL management
API Client
TypeScript Interfaces
interface Role {
id: string;
label: string;
}
interface RoleWithVoice extends Role {
voice: string;
}
interface RolesResponse {
roles: Role[];
}
interface GenerateRequest {
text: string;
lang: string;
roles: { id: string; voice: string }[];
speed?: number;
}
API Functions
// Detect roles in text
async function detectRoles(text: string): Promise<RolesResponse>
// Generate audiobook
async function generateAudiobook(payload: GenerateRequest): Promise<Blob>
// Health check
async function checkHealth(): Promise<{ status: string }>
Styling
Tailwind CSS
The application uses Tailwind CSS for styling:
- Utility-first CSS framework
- Responsive design
- Dark mode support (optional)
- Custom color palette
Responsive Design
Breakpoints:
- Mobile: < 640px
- Tablet: 640px - 1024px
- Desktop: > 1024px
All components are mobile-friendly with:
- Touch-friendly controls (min 44x44px)
- Responsive layouts
- Readable text sizes
- Appropriate spacing
Usage Workflow
1. Text Input Phase
User enters text with role markers:
Narrator: Once upon a time...
Alice: Hello there!
Bob: Hi Alice!
Supported patterns:
RoleName:- Colon pattern[RoleName]- Bracket pattern
2. Voice Assignment Phase
- System detects roles automatically
- User assigns voice to each role
- User selects language
- User adjusts speed (optional)
3. Audio Generation Phase
- Click "Generate Audiobook"
- Loading indicator shows progress
- Warning for long texts
4. Playback Phase
- Audio player appears
- Play/pause/seek controls
- Download button available
Error Handling
Network Errors
- Connection failures
- Timeout errors
- Server unavailable
Display: User-friendly error messages
Validation Errors
- Empty text
- Missing voice assignments
- Invalid configurations
Display: Inline validation messages
API Errors
- 400 Bad Request
- 500 Internal Server Error
- Custom error messages
Display: Error banner with details
Testing
Run Tests
npm test
Test Coverage
npm run test:coverage
Test Files
- Component tests
- API client tests
- Integration tests
- E2E tests (optional)
Browser Support
Supported Browsers
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Opera 76+
Required Features
- ES2020 support
- Fetch API
- HTML5 Audio
- Blob API
- Local Storage (optional)
Performance
Optimization Techniques
- Code splitting: Dynamic imports for large components
- Lazy loading: Load components on demand
- Memoization: React.memo for expensive components
- Debouncing: Input handlers
- Asset optimization: Image compression, lazy loading
Performance Monitoring
# Analyze bundle size
npm run build -- --analyze
# Lighthouse audit
npm run lighthouse
Deployment
Static Hosting
The built application can be deployed to:
- Vercel
- Netlify
- GitHub Pages
- AWS S3 + CloudFront
- Any static file server
Deployment Steps
-
Build the application:
npm run build -
Configure environment variables for production
-
Deploy
dist/directory to hosting service
Environment Variables in Production
Set VITE_API_BASE_URL to your production backend URL:
Vercel:
vercel env add VITE_API_BASE_URL
Netlify:
Add to netlify.toml:
[build.environment]
VITE_API_BASE_URL = "https://api.yourdomain.com"
Example nginx Configuration
server {
listen 80;
server_name yourdomain.com;
root /var/www/text-to-audiobook;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Troubleshooting
Cannot connect to backend
Error: Network request failed
Solutions:
- Verify backend is running:
curl http://localhost:8000/api/health - Check
VITE_API_BASE_URLin.env - Verify CORS settings in backend
- Check browser console for details
Audio won't play
Error: Audio playback failed
Solutions:
- Check browser console for errors
- Verify audio format support (WAV)
- Try different browser
- Check audio permissions
Build fails
Error: Build errors
Solutions:
# Clear cache
rm -rf node_modules dist
npm install
# Check Node version
node --version # Should be 20.19+ or 22.12+
# Update dependencies
npm update
TypeScript errors
Error: Type checking fails
Solutions:
# Run type check
npm run type-check
# Check tsconfig.json
# Verify all dependencies have types
Styling issues
Error: Tailwind classes not working
Solutions:
# Rebuild Tailwind
npm run build
# Check tailwind.config.js
# Verify PostCSS configuration
Development Tips
Hot Reload Issues
If HMR stops working:
# Restart dev server
npm run dev
# Clear Vite cache
rm -rf node_modules/.vite
Debugging
// Enable debug mode
localStorage.setItem('debug', 'true');
// View API requests
// Open browser DevTools → Network tab
Code Quality
# Format code
npm run format
# Lint and fix
npm run lint -- --fix
# Type check
npm run type-check
Contributing
Code Style
- Use TypeScript for type safety
- Follow React best practices
- Use functional components with hooks
- Write meaningful component names
- Add comments for complex logic
Component Guidelines
- Keep components small and focused
- Use props for configuration
- Lift state up when needed
- Use custom hooks for reusable logic
- Handle errors gracefully
Additional Resources
- React Documentation
- TypeScript Documentation
- Vite Documentation
- Tailwind CSS Documentation
- Main Project README
- Backend Documentation
- Design Document
License
MIT