Add Text-to-Speech to Any Website with 3 Lines of JavaScript
Add Text-to-Speech to Any Website with 3 Lines of JavaScript
Your website has great content. But not everyone reads it the same way. Some users have visual impairments, some have learning disabilities, and some simply prefer listening over reading. Text-to-speech makes your content accessible to all of them.
The problem? Building a TTS player from scratch is painful. You have to deal with the Web Speech API quirks, voice loading race conditions, the Chrome 15-second speech bug, UI controls, mobile compatibility, and more.
text-to-speech-tts is an npm package that handles all of this for you. Three lines of code, and your website has a fully functional TTS player.
Quick Start
Install it:
npm install text-to-speech-ttsUse it:
<link rel="stylesheet" href="node_modules/text-to-speech-tts/text-to-speech-tts.css">
<script src="node_modules/text-to-speech-tts/text-to-speech-tts.min.js"></script><div id="tts-player"></div>
<div id="article-body">
<p>Your article content goes here...</p>
</div><script>
var player = new AtlasVoice({
contentSelector: '#article-body',
playerSelector: '#tts-player',
});
</script>
That’s it. You now have a player with play/pause/resume controls, voice selection, language switching, and speed control. All powered by the voices already installed on the user’s device.
No API keys. No server. No cost.
What You Get
The SDK renders a complete player UI with:
- Play / Pause / Resume buttons
- Voice dropdown populated from the user’s device
- Language dropdown with all available locales
- Word count and estimated reading time
- Two themes (default and minimal)
It reads content from any DOM element using a CSS selector. Just point it at an article, a blog post, a product description, or any text container.
Three Ways to Load It
The package works in all JavaScript environments:
Script Tag
<script src="https://unpkg.com/text-to-speech-tts/text-to-speech-tts.min.js"></script>
<script>
var player = new AtlasVoice({
contentSelector: '#my-article',
playerSelector: '#player',
});
</script>CommonJS (Webpack, Browserify)
const AtlasVoice = require('text-to-speech-tts');const player = new AtlasVoice({
contentSelector: '#my-article',
playerSelector: '#player',
});ES Modules (Vite, Rollup)
import AtlasVoice from 'text-to-speech-tts';const player = new AtlasVoice({
contentSelector: '#my-article',
playerSelector: '#player',
});Full Configuration
You can customize everything:
const player = new AtlasVoice({
contentSelector: '#article-body',
playerSelector: '#tts-player',
lang: 'en-US',
rate: 1, // 0.1 to 10
pitch: 1, // 0 to 2
volume: 1, // 0 to 1
theme: 'default', // 'default' or 'minimal'
});Available Options
OptionTypeDefaultWhat it doescontentSelectorstring''CSS selector for the text to readplayerSelectorstring''CSS selector for the player containerlangstring'en-US'Default languagevoiceNamestring''Preferred voice nameratenumber1Speech speedpitchnumber1Voice pitchvolumenumber1Volume levelthemestring'default'UI theme
Listening to Events
The player emits events you can hook into:
player.on('play', () => console.log('Started playing'));
player.on('pause', () => console.log('Paused'));
player.on('resume', () => console.log('Resumed'));
player.on('end', () => console.log('Finished'));
player.on('stop', () => console.log('Stopped'));
player.on('error', (e) => console.error('Error:', e));
player.on('voiceschanged', (voices) => {
console.log(`${voices.length} voices available`);
});Programmatic Control
You can control the player entirely from code:
player.play();
player.pause();
player.resume();
player.stop();player.setRate(1.5); // Speed up
player.setPitch(0.8); // Lower pitch
player.setVolume(0.5); // Half volume
player.setVoice('Google UK English Female');
player.setLang('fr-FR'); // Switch to Frenchconst voices = player.getVoices(); // All available voices
const languages = player.getLanguages(); // All available languagesplayer.destroy(); // Cleanup when done
Styling the Player
The player uses CSS custom properties. Override them to match your site:
.atlasvoice-player {
--av-primary: #2563eb;
--av-primary-hover: #1d4ed8;
--av-bg: #f8fafc;
--av-text: #1e293b;
--av-border: #e2e8f0;
--av-radius: 12px;
}Analytics (Optional)
If you’re using the Text to Audio WordPress plugin, the SDK can send analytics data to your WordPress site. This works cross-domain, so you can embed the player on abc.com and track data on your WordPress site at xyz.com.
What gets tracked
- Play, pause, resume, and end event counts
- Total listening time in seconds
- Device info (browser, OS, device type, language, timezone)
- Unique visitor ID (via browser fingerprinting)
Setup
const player = new AtlasVoice({
contentSelector: '#article-body',
playerSelector: '#tts-player',
analytics: {
enabled: true,
wpRestUrl: 'https://your-wordpress-site.com/wp-json',
postId: 123,
credentials: {
username: 'your-username',
password: 'XXXX XXXX XXXX XXXX XXXX XXXX'
}
}
});The credentials use WordPress Application Passwords (generated from Users > Your Profile > Application Passwords in WP admin). Analytics data is accumulated in sessionStorage and automatically sent when the user leaves the page.
How It Works Under the Hood
The SDK is built on the browser’s native Web Speech API (window.speechSynthesis). Here's what it handles so you don't have to:
Get Atlasaidev’s stories in your inbox
Join Medium for free to get updates from this writer.
Voice loading The Web Speech API loads voices asynchronously, and the timing varies across browsers. The SDK retries up to 10 times with 100ms delays to ensure voices are available.
Chrome’s 15-second bug Chrome cancels speech after ~15 seconds of continuous playback. The SDK works around this with a pause/resume cycle every 10 seconds, completely transparent to the user.
Sentence-based playback Content is split into sentences. When you pause and resume, playback continues from the exact sentence, not from the beginning.
Content cleaning HTML tags, shortcodes, URLs, and special characters are stripped before speaking. The SDK cleans the raw HTML into natural-sounding text.
Cross-browser compatibility Works on Chrome, Edge, Firefox, and Safari. Handles the differences in voice APIs, sendBeacon behavior, and speech synthesis quirks across browsers.
TypeScript Support
The package includes TypeScript declarations out of the box:
import AtlasVoice from 'text-to-speech-tts';const player = new AtlasVoice({
contentSelector: '#article',
playerSelector: '#player',
lang: 'en-US',
rate: 1.2,
});player.on('play', () => { /* typed */ });
player.on('voiceschanged', (voices: SpeechSynthesisVoice[]) => {
console.log(voices.length);
});
Real-World Use Cases
Blog / News sites Let readers listen to articles while commuting or doing chores.
E-learning platforms Students can listen to lesson content, improving retention for auditory learners.
Documentation sites Developers can listen to docs while coding in another window.
E-commerce Product descriptions read aloud for better accessibility compliance.
Multilingual sites The SDK auto-detects available voices per language. Switch between English, Spanish, French, German, and 100+ other languages.
WordPress Integration
The SDK was built as a companion to the Text to Audio WordPress plugins:
- Text to Audio (Free) Text-to-speech using browser voices. Install it, and your WordPress posts get a TTS player.
- Text to Speech Pro (Pro) Adds server-side voices: Google Cloud TTS, gTTS, and ChatGPT/OpenAI TTS. Five player styles and premium voice quality.
The npm package lets you use the same TTS functionality outside of WordPress, on any website, while optionally sending analytics back to your WordPress site.
Links
- npm: npmjs.com/package/text-to-speech-tts
- WordPress plugin (Free): wordpress.org/plugins/text-to-audio
- WordPress plugin (Pro): atlasaidev.com/plugins/text-to-speech-pro
- Author: AtlasAiDev
If you found this useful, give the npm package a star and the WordPress plugin a rating. It helps more developers find it.




