A lightweight, modular Svelte component for text-to-speech with synchronized word and paragraph highlighting. Perfect for creating accessible content with visual feedback.
npm install svelte-tts-highlighter
# or
pnpm add svelte-tts-highlighter
# or
yarn add svelte-tts-highlighter
The library is structured in a modular way, allowing you to use it according to your needs:
<script lang="ts">
import { useSpeechHighlight } from 'svelte-tts-highlighter';
const text = "Welcome to our demo. This is a test.";
const { useHandler, speechStore } = useSpeechHighlight({
speechRate: 1,
speechPitch: 1,
speechLang: 'en-US'
});
const { paragraphsItems, toggleSpeech } = useHandler(text);
$: ({ isPlaying, currentWordIndex, currentParagraphIndex } = $speechStore);
</script>
<button on:click={toggleSpeech}>
{isPlaying ? 'Stop' : 'Start'} Speech
</button>
<div class="paragraphs">
{#each paragraphsItems as { words, prevWordsOffset }, i}
<p class:active={i === currentParagraphIndex}>
{#each words as word, j}
<span class:highlight={j + prevWordsOffset === currentWordIndex}>
{word}
</span>
{/each}
</p>
{/each}
</div>
The library consists of three main modules:
import { speechStore } from "svelte-tts-highlighter";
// Access store values
$: ({ isPlaying, currentWordIndex, currentParagraphIndex } = $speechStore);
import { type ParagraphItem, type SpeechState } from "svelte-tts-highlighter";
import { useSpeechHighlight } from "svelte-tts-highlighter";
const { useHandler, speechStore } = useSpeechHighlight({
speechRate?: number; // default: 1
speechPitch?: number; // default: 1
speechLang?: string; // default: 'en-US'
});
const { paragraphsItems, toggleSpeech } = useHandler(text: string);
interface SpeechState {
isPlaying: boolean;
currentWordIndex: number;
currentParagraphIndex: number;
}
interface ParagraphItem {
words: string[];
wordsOffset: number;
prevWordsOffset: number;
text: string;
}
Add your own CSS to style the highlighted words and paragraphs:
.highlight {
background-color: #3d5413;
color: white;
}
.active {
background-color: rgba(128, 128, 128, 0.2);
}
span {
margin-right: 0.3em;
padding: 0.1em 0.2em;
border-radius: 3px;
transition: background-color 0.2s ease;
}
This component uses the Web Speech API. Check browser compatibility for support details.
MIT
Contributions are welcome! Please feel free to submit a Pull Request.