{"id":27943546,"url":"https://github.com/ethanngit/azurettsreactjsnodejsintegration","last_synced_at":"2026-01-23T12:56:35.956Z","repository":{"id":212374580,"uuid":"731332911","full_name":"EthanNgit/AzureTTSReactJsNodeJSIntegration","owner":"EthanNgit","description":"Tutorial on how to integrate Azure Text to Speech api into a web app using React JS frontend and Node JS backend","archived":false,"fork":false,"pushed_at":"2023-12-13T22:17:10.000Z","size":13,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T12:12:37.418Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EthanNgit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-13T21:06:27.000Z","updated_at":"2023-12-13T21:06:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"3ee97310-b97b-4211-82f3-955eb2f70a90","html_url":"https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration","commit_stats":null,"previous_names":["ethanngit/azurettsreactjsnodejsintegration"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/EthanNgit/AzureTTSReactJsNodeJSIntegration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EthanNgit%2FAzureTTSReactJsNodeJSIntegration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EthanNgit%2FAzureTTSReactJsNodeJSIntegration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EthanNgit%2FAzureTTSReactJsNodeJSIntegration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EthanNgit%2FAzureTTSReactJsNodeJSIntegration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EthanNgit","download_url":"https://codeload.github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EthanNgit%2FAzureTTSReactJsNodeJSIntegration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28692445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T11:01:27.039Z","status":"ssl_error","status_checked_at":"2026-01-23T11:00:26.909Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-07T12:12:36.715Z","updated_at":"2026-01-23T12:56:35.943Z","avatar_url":"https://github.com/EthanNgit.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# AzureTTS integration with ReactJs NodeJS\nIntegrating Azure TTS into a React and Node based webapp can be difficult, but here was my solution to this problem. This assumes you already have a working webapp and routes set up. If you do not follow an online tutorial to get started.\n\n## Step 1: Setup Project\nInstall express and configure your roots, if you need the npm its here.\n```\nnpm install express\n```\nThen after its configured, again if you need it look it up, in your file that routes the apis (typically index) do the following\n```\n// Create router\nconst ttsRouter = require('./routes/tts-call');\n// Use router\napp.use(\"/api/tts/\", ttsRouter);\n```\n## Step 2: Setup Microsoft Azure account\n\nMicrosoft Azure TTS is free up to 500k characters per month, and then it can incur charges (if you set your account up to do so). Microsoft Azure has plenty of realistic voices, making it ideal for small productions.\n\n### 1. [Sign up](https://azure.microsoft.com/en-us) for your Azure account (you will need to input a card).\n\n### 2. Create an instance\n\n- Head to your portal and click the \"More Services\" arrow:\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/2b2951d1-f305-41b4-8927-65b38f82b5ec)\n\n- Click \"Speech Services\":\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/b65ce27d-9d21-4acb-9ca0-cd02456c4de5)\n\n- Click \"Create\":\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/c7a1c070-2255-4f20-81a5-536ee838b10b)\n\n- Choose the available subscription, create a new resource group (something like \"project-one-resource\"), then choose a name and region for this instance. If you want to use the free trial (500k per month max), select the free tier, \"Free, F(0)\".\n\n### 3. Get information\n\n- Get the key and region ready for use later; you will need it.\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/8f840cf3-1afd-42e5-956e-f10a52f8bfac)\n\n### Side Note: Voices\n\n- If you want to figure out the voice you want now, you can also click the \"Voice Studio\" button.\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/3899dfec-e1ee-4a98-ac17-2ad1f0e603ef)\n\n- Scroll down to \"Voice Gallery\" and click it.\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/15f54f92-bda2-4f65-bfb6-49e00145239a)\n\n- Here you can go through all languages and voices available and also note the emotion and styles the voices can show. Keep in mind that trying custom lines will use out of your free 500k.\n  ![image](https://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/e31522ea-2252-4e2c-b80a-ef7704c5475d)\n  \n- If you want to use the voice find it [here](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts) and save the tag for it\n\u003cbr\u003e\n\n## Step 3: Create Route\nNext you can create a file in your backend routes file. I used tts-call.js. Since we are using express you can do the following\n```\nconst express = require(\"express\");\nconst { PassThrough } = require(\"nodemailer/lib/xoauth2\");\n\nconst router = express.Router();\n\nrouter.post(\"/\", async (req, res) =\u003e {\n    const { text } = req.body;\n\n    // Enter your key (either key1 or key2) from the azure instance\n    const subscriptionKey = \"YOUR_SUBSCRIPTION_KEY\";\n    // Enter the region that you can find from your azure instance (eg eastus)\n    const serviceRegion = 'YOUR_REGION';\n\n    try {\n        const sdk = await import(\"microsoft-cognitiveservices-speech-sdk\");\n        \n        const speechConfig = sdk.SpeechConfig.fromSubscription(\n            subscriptionKey,\n            serviceRegion\n        );\n\n        speechConfig.speechSynthesisOutputFormat =\n            sdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;\n\n        const synthesizer = new sdk.SpeechSynthesizer(speechConfig, null);\n\n        // Here you can add your voice (eg zh-CN-XiaoxiaoNeural)\n        // You will also have to find your language (found in the language options documentations above eg zh-CN)\n        // You can also add other modifiers if the voice allows you too\n        // There is a list in the documentation marked below for all the modifiers but you add it like so \n        // \u003cvoice name=\"YOUR_TTS_VOICE\" modifier=\"YOUR_MODIFIER_SETTING\" modifier2=\"YOUR_MODIFIER_SETTING\"\u003e\n        synthesizer.speakSsmlAsync(\n            `\n            \u003cspeak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\"\n            xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"YOUR_LANGUAGE\"\u003e\n            \u003cvoice name=\"YOUR_TTS_VOICE\"\u003e\n                    ${text}\n            \u003c/voice\u003e\n            \u003c/speak\u003e\n            `,\n            result =\u003e {\n                const { audioData} = result;\n\n                synthesizer.close();\n\n                const bufferStream = Buffer.from(audioData);\n                res.set('Content-Type', 'audio/mpeg');\n                res.send(bufferStream);\n            }\n        );\n    } catch (error) {\n        console.error('Error:', error);\n        res.status(500).send('Internal Server Error');\n    }\n});\n\nmodule.exports = router;\n\n```\n\n\u003e This is the documentation for voice settings [here](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/speech-synthesis-markup-voice)\n\n## Step 4: API usage from the frontend.\nNow that it is established in the backend to call to the azure tts api, you can call it from your frontend. Below is simple version (make sure you have axios installed frontend to call apis)\n```\n    const response = await axios.post('http://localhost:3000/api/tts', { text }, { responseType: 'arraybuffer' });\n    \n    const audioArrayBuffer = response.data;\n    const audioBlob = new Blob([audioArrayBuffer], { type: 'audio/mpeg' });\n    const audioUrl = URL.createObjectURL(audioBlob);\n    const audioElement = new Audio(audioUrl);\n\n    await audioElement.play();\n```\nWhat this does is gets the tts buffer array given your input text, and then creates a blob out of it using mpeg (mp3), then creates a url to be called, then uses a audio element to play it, and then plays it.\nHere is a more advanced usage, using a button to play the audio as a React component, you need the font awesome package as well.\n```\nimport { faVolumeHigh } from '@fortawesome/free-solid-svg-icons/faVolumeHigh'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport axios from 'axios';\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'\n\ninterface TextToSpeechProps {\n    text: string;\n}\n\nconst TTSButton: React.ForwardRefRenderFunction\u003cany, TextToSpeechProps\u003e = ({ text }, ref) =\u003e {\n  const [audioBuffer, setAudioBuffer] = useState\u003cArrayBuffer | null\u003e(null);\n  const [isPlaying, setIsPlaying] = useState(false);\n  const iconRef = useRef\u003cnull | SVGSVGElement\u003e(null);\n  \n    const playAudio = async () =\u003e {\n      if (!isPlaying) {\n        try {\n          setIsPlaying(true);\n  \n          if (audioBuffer) {\n            const audioArrayBuffer = audioBuffer;\n            const audioBlob = new Blob([audioArrayBuffer], { type: 'audio/mpeg' });\n            const audioUrl = URL.createObjectURL(audioBlob);\n            const audioElement = new Audio(audioUrl);\n\n            audioElement.addEventListener('ended', () =\u003e {\n              setIsPlaying(false);\n            });\n\n            await audioElement.play();\n\n            console.log(\"Played saved audio\");\n          } else {\n            const response = await axios.post('http://localhost:3001/api/tts', { text }, { responseType: 'arraybuffer' });\n            setAudioBuffer(response.data);\n            \n            const audioArrayBuffer = response.data;\n            const audioBlob = new Blob([audioArrayBuffer], { type: 'audio/mpeg' });\n            const audioUrl = URL.createObjectURL(audioBlob);\n            const audioElement = new Audio(audioUrl);\n\n            audioElement.addEventListener('ended', () =\u003e {\n              setIsPlaying(false);\n            });\n\n            await audioElement.play();\n\n            console.log(\"Played new audio\");\n          }\n        } catch (error) {\n          console.error('Error playing audio:', error);\n        } \n      }\n    };\n\n    useEffect(() =\u003e {\n      return () =\u003e {\n        setAudioBuffer(null);\n        setIsPlaying(false);\n      };\n    }, [text]);\n\n    useImperativeHandle(ref, () =\u003e ({\n      forceClick: playAudio,\n    }));\n  \n    return (\n      \u003cFontAwesomeIcon icon={faVolumeHigh} className='cn-listen-icon' onClick={playAudio} ref={iconRef} /\u003e\n    );\n  };\n  \n  export default forwardRef(TTSButton);\n```\nYou can use it like\n```\n\u003cTTSButton text=\"TEXT_YOU_WANT_SPOKEN\" /\u003e\n```\n\n## Step 5: Finish\nThat is all it took, its really simple, and rewarding compared to other tts options avaliable given the generous free trial.\n\nhttps://github.com/EthanNgit/AzureTTSReactJsNodeJSIntegration/assets/105979510/ad7fd088-d78c-41ec-ab5f-a6c2dd160641\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanngit%2Fazurettsreactjsnodejsintegration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethanngit%2Fazurettsreactjsnodejsintegration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanngit%2Fazurettsreactjsnodejsintegration/lists"}