I started this blog post experimenting with Eleven Labs to turn text into speech within the context of a Vue project. What I ended up with was a Nuxt layer for turning Nuxt content markdown files into realistic sounding speech.
Say hello to Nuxt Content Narrator, a powerful new layer for Nuxt Content that brings text-to-speech capabilities to your content pages. This solution seamlessly integrates Nuxt Content with Eleven Labs’ state-of-the-art voice synthesis technology to create natural, engaging audio versions of your Markdown content.
Getting up and running with Nuxt Content Narrator is straightforward. Here’s how to add narration capabilities to your Nuxt Content site:
First, install the layer using npm:
npm i nuxt-content-narrator
Then extend it in your Nuxt configuration:
// nuxt.config.ts
extends: ["nuxt-content-narrator"],
You’ll need an ElevenLabs API key to generate the voice narration. Once you have your key from ElevenLabs, set it as an environment variable. (Note: Eleven Labs is a premium product and the cost of generating audio will increase as the size of the content increases.)
NUXT_ELEVENLABS_API_KEY=sk_xxx
The narrator system consists of several components that work together to provide a complete text-to-speech solution. Included components are:
Here’s a basic implementation example:
<script setup lang="ts">
const route = useRoute();
// fetch your content using Nuxt Content's built in queryCollection function
const { data: story } = await useAsyncData(() =>
queryCollection("stories")
.path(route.path.toString() ?? "")
.first()
);
</script>
<template>
<article class="prose prose-lg mx-auto">
<!-- Wrap the content in the NcNarratorService -->
<NcNarratorService
v-if="story"
:collection-item="story"
voiceId="FGY2WhTYpPnrIDTdsKH5"
>
<!--Display the player-->
<NcNarratorPlayer progressClass="bg-gray-900" />
<!--Display a button to generate audio in development-->
<NcNarratorDevTools />
<!--
Optionally use the Follow Along Renderer for synchronized text
highlighting. If no highlighting is needed use the
normal <ContentRenderer/>
-->
<NcNarratorFollowAlongRenderer
highlightClass="bg-gray-900"
highlightTextClass="text-white"
/>
</NcNarratorService>
</article>
</template>
Once you’ve got the components setup on a content page you should use the button provided by the NcNarratorDevtools
to generate the audio for the current page content.
If no audio is found, playing the audio for the first time will generate it on the fly (which will take a little time depending on the content length) but if you want to update the audio because you’ve updated a post, you’ll need to force generate it with this button.
By default generated audio is stored in a directory named audio
at the project root along with timings. You should generate audio on your local machine in development and then save it to the github repo.
Alternately, you can store audio to other storage services like an Amazon s3 bucket or Netlify blobs with a custom nitro storage configuration:
// nuxt.config.ts
nitro: {
devStorage: {
audio: {
driver: "[your choice]", // https://unstorage.unjs.io/drivers
},
},
},
To customize the voice used for narration you can pass in a voiceId
to the NcNarratorService
component. This means you can hardcode the voice id for a consistent feel throughout your site or provide it dynamically to customize the voice per page.
You can browse the voices available on the Elevenlabs website and snag the id from the url by clicking the “View” button on the desired voice.
Browse Eleven Labs voices on their website and pick the id of the voice that best fits your needs
If the style of the built-in player doesn’t fit your needs, you can customize the rendering 100% with it’s default slot.
<NcNarratorPlayer
v-slot="{
play, // function to play the audio
pause, // function to pause the audio
toggle, // function to toggle the audio
playing, // boolean to check if the audio is playing
currentTime, // number to get the current time of the audio
duration, // number to get the duration of the audio
percentComplete // number to get the percent complete of the audio
}"
>
<!-- Your custom player UI -->
</NcNarratorPlayer>
The synchronized text feature allows the user to follow along with the audio and can handle many different formats like headings, lists, code, bold, italic, etc. Below is a demonstration of how it works.
As you can tell, right now the list handling could use a little more work to make it sound more natural and code blocks are simply skipped in narration but otherwise the various content types have pretty good support!
Nuxt Content Narrator brings a new dimension to your content by making it accessible through high-quality voice narration with very little effort. Whether you’re building a blog, documentation site, or any content-rich application, this layer makes it easy to add professional text-to-speech capabilities to your Nuxt Content pages.
Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.
More than 200.000 users have already joined us. You are welcome too!
© All rights reserved. Made with ❤️ by BitterBrains, Inc.