A client asked me for a way to read out case updates for visually impaired users, and that is when I realised how little work a Text-to-Speech LWC actually takes. You don't need an expensive third-party integration or a heavy library to make your Salesforce org talk to you. Most modern browsers already do the work for us through the Web Speech API.
Why you should consider Text-to-Speech LWC for your next project
We tend to think of accessibility as high-contrast colors and screen reader support. Giving a user a native way to hear text is a big win on top of that. I've seen teams add it to Experience Cloud portals for people who struggle with long blocks of text, and it puts a bit of personality into a custom component along the way.
Voice is also becoming the standard as more of the platform leans on AI. If you're looking into Agentforce use cases, a component that can actually speak the agent's response makes the whole experience feel more natural. It all runs in the browser, so none of it counts against your Salesforce governor limits.
Building a basic Text-to-Speech LWC from scratch
You work with the speechSynthesis interface, which is part of the Web Speech API. Create an "utterance" (the text you want spoken), tell the browser which voice to use, and hit play. Here is how I usually structure the code.
The JavaScript logic
One thing that trips people up is that voices don't always load immediately. Check that the browser supports speech before you try to run the function. Here's a clean way to handle the logic:
import { LightningElement, track } from 'lwc';
export default class TextToSpeechLwc extends LightningElement {
@track textToSpeak = 'Welcome to the Salesforce ecosystem!';
handleInputChange(event) {
this.textToSpeak = event.target.value;
}
speak() {
if (!window.speechSynthesis) {
console.error('This browser does not support text-to-speech.');
return;
}
// Always stop any current speech before starting new audio
window.speechSynthesis.cancel();
const utterance = new SpeechSynthesisUtterance(this.textToSpeak);
utterance.lang = 'en-US';
// Grab the available voices from the browser
const voices = window.speechSynthesis.getVoices();
if (voices.length > 0) {
// I usually just grab the first English voice found
utterance.voice = voices.find(v => v.lang.includes('en')) || voices[0];
}
window.speechSynthesis.speak(utterance);
}
}
The HTML template
The UI can stay plain. A textarea and a button do the job. If you're building something more involved, LWC component communication lets you trigger the speech from a parent component.
<template>
<lightning-card title="Voice Assistant" icon-name="utility:volume_high">
<div class="slds-var-p-around_medium">
<lightning-textarea
label="Enter text to hear it aloud"
value={textToSpeak}
onchange={handleInputChange}>
</lightning-textarea>
<lightning-button
label="Speak Now"
onclick={speak}
variant="brand"
class="slds-var-m-top_small">
</lightning-button>
</div>
</lightning-card>
</template>
Real-world tips for the Text-to-Speech LWC
Just because your app can talk doesn't mean it should talk all the time. Most teams get this wrong by making it too intrusive. Here's what I've learned from running this in production orgs:
- Don't auto-play. Browsers usually block audio that starts without a user click anyway, so wait for the user to trigger the speech.
- Add a stop button. There is nothing more annoying than a three-minute paragraph you can't silence. Use
window.speechSynthesis.cancel()to give users control. - Check mobile. Safari on iOS can be picky with the Web Speech API, so test on a physical device rather than the Chrome emulator.
- Watch the language. If your users are global, don't hardcode 'en-US'. Grab the user's locale from Salesforce and match the voice accordingly.
Pro Tip: The
getVoices()method is often called asynchronously. If it returns an empty list the first time, you might need to listen for thevoiceschangedevent before selecting a voice.
Key takeaways
- A Text-to-Speech LWC is a browser-native way to improve accessibility without extra costs.
- Use
speechSynthesis.cancel()before every new utterance to prevent overlapping audio. - Always provide a clear UI control so users can start and stop the voice as they please.
- This approach works well for Experience Cloud sites and custom internal tools.
Is a Text-to-Speech LWC something every org needs? Probably not. For a specific accessibility requirement, or for making a custom app feel more modern, it's worth keeping in your back pocket. It's lightweight and needs no server-side Apex logic. Try it in your sandbox and see how it changes the user experience.
Leave a Comment