Skip to content

useVoiceQueue ​

Low-level composable that manages a first-in-first-out queue of text utterances. useStreamingTTS builds on top of this composable.

Import ​

ts
import { useVoiceQueue } from 'vue-text-to-speech'

Usage ​

vue
<script setup lang="ts">
import { useVoiceQueue } from 'vue-text-to-speech'

const { enqueue, clear, skip, queue, currentItem, isPlaying } = useVoiceQueue()

function addItems() {
  enqueue('First sentence.')
  enqueue('Second sentence.')
  enqueue('Third sentence.')
}
</script>

<template>
  <button @click="addItems()">Queue sentences</button>
  <button @click="clear()">Clear</button>
  <p>Playing: {{ currentItem }}</p>
  <ul>
    <li v-for="item in queue" :key="item">{{ item }}</li>
  </ul>
</template>

Parameters ​

ts
interface UseVoiceQueueOptions {
  /** Override the injected provider for this queue instance */
  provider?: TTSProvider
}

function useVoiceQueue(options?: UseVoiceQueueOptions): UseVoiceQueueReturn

Return Value ​

ts
interface UseVoiceQueueReturn {
  /** Add a text item to the end of the queue */
  enqueue(text: string): void
  /**
   * Manually pop the next item from the queue without speaking it.
   * Returns the item, or undefined if the queue is empty.
   */
  dequeue(): string | undefined
  /** Stop the current utterance and discard all pending items */
  clear(): void
  /**
   * Stop the current utterance immediately.
   * The queue auto-advances to the next item via the provider's onEnd hook.
   */
  skip(): void
  /** Items waiting to be spoken (does not include the currently-speaking item) */
  queue: Readonly<Ref<readonly string[]>>
  /** The item currently being spoken */
  currentItem: Readonly<Ref<string | null>>
  /** True while any item is playing */
  isPlaying: Readonly<Ref<boolean>>
}

Queue Lifecycle ​

enqueue('A') ─► queue: ['A']           currentItem: null
enqueue('B') ─► queue: ['A', 'B']      currentItem: null
[A starts]   ─► queue: ['B']           currentItem: 'A'
[A finishes] ─► queue: []              currentItem: 'B'
[B starts]   ─► queue: []              currentItem: 'B'
[B finishes] ─► queue: []              currentItem: null

Concurrency ​

useVoiceQueue plays exactly one item at a time. Playback of the next item starts automatically after the previous one finishes. Calling enqueue() while an item is playing appends to the queue without interrupting playback.

Clearing the Queue ​

clear() stops the currently playing item and removes all pending items:

ts
const { enqueue, clear } = useVoiceQueue()

enqueue('Long sentence one...')
enqueue('Long sentence two...')

// Immediately stops 'one' and removes 'two'
clear()

Relation to useStreamingTTS ​

useStreamingTTS wraps useVoiceQueue and adds:

  1. An AsyncIterable<string> input pipe
  2. Sentence boundary detection via Intl.Segmenter
  3. AbortController-based stream cancellation

Use useVoiceQueue directly when you have discrete pre-segmented sentences or paragraphs to play.

Released under the MIT License.