| 
 | 1 | +---  | 
 | 2 | +layout: post  | 
 | 3 | +title: Speech-to-Text with Blazor Chat UI Component | Syncfusion  | 
 | 4 | +description: Checkout and learn about Speech-to-Text configuration with Blazor Chat UI component in Blazor Server App and Blazor WebAssembly App.  | 
 | 5 | +platform: Blazor  | 
 | 6 | +control: Chat UI  | 
 | 7 | +documentation: ug  | 
 | 8 | +---  | 
 | 9 | + | 
 | 10 | +# Speech-to-Text in Blazor Chat UI  | 
 | 11 | + | 
 | 12 | +The Syncfusion Blazor Chat UI component integrates `Speech-to-Text` functionality through the browser's [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API). This enables the conversion of spoken words into text using the device's microphone, allowing users to interact with the Chat UI through voice input.  | 
 | 13 | + | 
 | 14 | +## Configure Speech-to-Text  | 
 | 15 | + | 
 | 16 | +To enable Speech-to-Text functionality in the Blazor Chat UI component, update the `Home.razor` file to incorporate the Web Speech API.  | 
 | 17 | + | 
 | 18 | +The [SpeechToText](https://blazor.syncfusion.com/documentation/speech-to-text/getting-started-web-app) component listens to audio input from the device’s microphone, transcribes spoken words into text, and updates the Chat UI’s editable footer using the [FooterTemplate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.InteractiveChat.SfChatUI.html#Syncfusion_Blazor_InteractiveChat_SfChatUI_FooterTemplate) tag directive to display the transcribed text. Once the transcription appears in the footer, users can send it as a message to others.  | 
 | 19 | + | 
 | 20 | +### Configuration Options  | 
 | 21 | + | 
 | 22 | +* **[`Language`](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.SfSpeechToText.html#Syncfusion_Blazor_Inputs_SfSpeechToText_Language)**: Specifies the language for speech recognition. For example:  | 
 | 23 | + | 
 | 24 | +    * `en-US` for American English  | 
 | 25 | +    * `fr-FR` for French  | 
 | 26 | + | 
 | 27 | +* **[`AllowInterimResults`](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.SfSpeechToText.html#Syncfusion_Blazor_Inputs_SfSpeechToText_AllowInterimResults)**: Set to `true` to receive real-time (interim) recognition results, or `false` to receive only final results.  | 
 | 28 | + | 
 | 29 | +The `speechtotext.js` file handles operations related to the content of the editable footer, such as checking for meaningful input, clearing existing text, and updating the content with the transcribed value. Meanwhile, the `speechtotext.css` file styles the Chat UI layout and ensures the component remains responsive across different screen sizes and devices.  | 
 | 30 | + | 
 | 31 | +{% tabs %}  | 
 | 32 | +{% highlight c# tabtitle="razor" %}  | 
 | 33 | + | 
 | 34 | +@using Syncfusion.Blazor.InteractiveChat  | 
 | 35 | +@using Syncfusion.Blazor.Buttons  | 
 | 36 | +@using Syncfusion.Blazor.Inputs  | 
 | 37 | +@inject IJSRuntime JSRuntime  | 
 | 38 | + | 
 | 39 | +<div class="integration-speechtotext">  | 
 | 40 | +    <SfChatUI @ref="chatUI" ID="chatUser" AutoScrollToBottom=true User="CurrentUserModel" Messages="ChatUserMessages">  | 
 | 41 | +        <FooterTemplate>  | 
 | 42 | +            <div class="e-footer-wrapper">  | 
 | 43 | +                <div id="chatui-footer" class="content-editor" contenteditable="true" placeholder="Click to speak or start typing..." @oninput="@UpdateContent" @onkeydown="@OnKeyDown" @ref="@EditableDiv">@ChatUIFooterValue</div>  | 
 | 44 | +                <div class="option-container">  | 
 | 45 | +                    <SfSpeechToText ID="speechToText" TranscriptChanging="@OnTranscriptChange" SpeechRecognitionStopped="@HandleStopRecognition"  | 
 | 46 | +                    CssClass="@($"e-flat {SpeechToTextCssClass}")" Disabled="@DisabledState"></SfSpeechToText>  | 
 | 47 | +                    <SfButton ID="chatui-sendButton" IconCss="e-assist-send e-icons" CssClass="@ButtonCssClass" @onclick="SendButtonClicked"></SfButton>  | 
 | 48 | +                </div>  | 
 | 49 | +            </div>  | 
 | 50 | +        </FooterTemplate>  | 
 | 51 | +    </SfChatUI>  | 
 | 52 | +</div>  | 
 | 53 | +@code {  | 
 | 54 | +    private SfChatUI chatUI;  | 
 | 55 | +    private static UserModel CurrentUserModel = new UserModel() { ID = "User1", User = "Albert" };  | 
 | 56 | +    private static UserModel MichaleUserModel = new UserModel() { ID = "User2", User = "Michale Suyama" };  | 
 | 57 | +    private string ChatUIFooterValue = String.Empty;  | 
 | 58 | +    private ElementReference EditableDiv;  | 
 | 59 | +    private string FooterContent = String.Empty;  | 
 | 60 | +    private string SpeechToTextCssClass = "visible";  | 
 | 61 | +    private string ButtonCssClass = String.Empty;  | 
 | 62 | +    private bool DisabledState = false;  | 
 | 63 | + | 
 | 64 | +    private List<ChatMessage> ChatUserMessages = new List<ChatMessage>()  | 
 | 65 | +    {  | 
 | 66 | +        new ChatMessage() { Text = "Hi Michale, are we on track for the deadline?", Author = CurrentUserModel },  | 
 | 67 | +        new ChatMessage() { Text = "Yes, the design phase is complete.", Author = MichaleUserModel },  | 
 | 68 | +        new ChatMessage() { Text = "I’ll review it and send feedback by today.", Author = CurrentUserModel }  | 
 | 69 | +    };  | 
 | 70 | + | 
 | 71 | +    private async void OnTranscriptChange(TranscriptChangeEventArgs args)  | 
 | 72 | +    {  | 
 | 73 | +        ChatUIFooterValue = args.Transcript;  | 
 | 74 | +        await JSRuntime.InvokeVoidAsync("updateContentEditableDiv", EditableDiv, ChatUIFooterValue);  | 
 | 75 | +        await InvokeAsync(StateHasChanged);  | 
 | 76 | +    }  | 
 | 77 | +    private async Task UpdateContent()  | 
 | 78 | +    {  | 
 | 79 | +        FooterContent = await JSRuntime.InvokeAsync<String>("isFooterContainsValue", EditableDiv);  | 
 | 80 | +        ToggleVisibility();  | 
 | 81 | +    }  | 
 | 82 | +    private async Task HandleStopRecognition()  | 
 | 83 | +    {  | 
 | 84 | +        FooterContent = ChatUIFooterValue;  | 
 | 85 | +        ToggleVisibility();  | 
 | 86 | +        await InvokeAsync(StateHasChanged);  | 
 | 87 | +    }  | 
 | 88 | +    private void ToggleVisibility()  | 
 | 89 | +    {  | 
 | 90 | +        ButtonCssClass = string.IsNullOrWhiteSpace(FooterContent) ? "" : "visible";  | 
 | 91 | +        SpeechToTextCssClass = string.IsNullOrWhiteSpace(FooterContent) ? "visible" : "";  | 
 | 92 | +    }  | 
 | 93 | + | 
 | 94 | +    private async Task SendButtonClicked()  | 
 | 95 | +    {  | 
 | 96 | +        chatUI.Messages.Add(new ChatMessage() { Text = FooterContent, Author = CurrentUserModel });  | 
 | 97 | +        ChatUIFooterValue = String.Empty;  | 
 | 98 | +        await JSRuntime.InvokeVoidAsync("emptyFooterValue", EditableDiv);  | 
 | 99 | +        await UpdateContent();  | 
 | 100 | +        ToggleVisibility();  | 
 | 101 | +    }  | 
 | 102 | +    private async Task OnKeyDown(KeyboardEventArgs e)  | 
 | 103 | +    {  | 
 | 104 | +        if (e.Key == "Enter" && !e.ShiftKey)  | 
 | 105 | +        {  | 
 | 106 | +            await SendButtonClicked();  | 
 | 107 | +        }  | 
 | 108 | +    }  | 
 | 109 | +}  | 
 | 110 | + | 
 | 111 | +{% endhighlight %}  | 
 | 112 | + | 
 | 113 | +{% highlight c# tabtitle="speechtotext.js" %}  | 
 | 114 | + | 
 | 115 | +// Checks if the content editable element contains meaningful text and cleans up.  | 
 | 116 | +function isFooterContainsValue(elementref) {  | 
 | 117 | +    if (!elementref.innerText.trim() !== '') {  | 
 | 118 | +        if ((elementref.innerHTML === '<br>' || elementref.innerHTML.trim() === '')) {  | 
 | 119 | +            elementref.innerHTML = '';  | 
 | 120 | +        }  | 
 | 121 | +    }  | 
 | 122 | +    return elementref.innerText || "";  | 
 | 123 | +}  | 
 | 124 | +// Clears the text content of a content editable element.  | 
 | 125 | +function emptyFooterValue(elementref) {  | 
 | 126 | +    if (elementref) {  | 
 | 127 | +        elementref.innerText = "";  | 
 | 128 | +    }  | 
 | 129 | +}  | 
 | 130 | +// Updates the text content of a content editable element with a specified value.  | 
 | 131 | +function updateContentEditableDiv(element, value) {  | 
 | 132 | +    if (element) {  | 
 | 133 | +        element.innerText = value;  | 
 | 134 | +    }  | 
 | 135 | +}  | 
 | 136 | + | 
 | 137 | +{% endhighlight %}  | 
 | 138 | + | 
 | 139 | +{% highlight c# tabtitle="speechtotext.css" %}  | 
 | 140 | + | 
 | 141 | +.integration-speechtotext {  | 
 | 142 | +  height: 400px;  | 
 | 143 | +  width: 450px;  | 
 | 144 | +  margin: 0 auto;  | 
 | 145 | +}  | 
 | 146 | + | 
 | 147 | +.integration-speechtotext #chatui-sendButton {  | 
 | 148 | +  width: 40px;  | 
 | 149 | +  height: 40px;  | 
 | 150 | +  font-size: 15px;  | 
 | 151 | +  border: none;  | 
 | 152 | +  background: none;  | 
 | 153 | +  cursor: pointer;  | 
 | 154 | +}  | 
 | 155 | + | 
 | 156 | +.integration-speechtotext #speechToText.visible,  | 
 | 157 | +.integration-speechtotext #chatui-sendButton.visible {  | 
 | 158 | +  display: inline-block;  | 
 | 159 | +}  | 
 | 160 | + | 
 | 161 | +.integration-speechtotext #speechToText,  | 
 | 162 | +.integration-speechtotext #chatui-sendButton {  | 
 | 163 | +  display: none;  | 
 | 164 | +}  | 
 | 165 | + | 
 | 166 | +@@media only screen and (max-width: 750px) {  | 
 | 167 | +  .integration-speechtotext {  | 
 | 168 | +    width: 100%;  | 
 | 169 | +  }  | 
 | 170 | +}  | 
 | 171 | + | 
 | 172 | +.integration-speechtotext .e-footer-wrapper {  | 
 | 173 | +  display: flex;  | 
 | 174 | +  border: 1px solid #c1c1c1;  | 
 | 175 | +  margin: 5px 5px 0 5px;  | 
 | 176 | +  border-radius: 10px;  | 
 | 177 | +  padding: 5px;  | 
 | 178 | +}  | 
 | 179 | + | 
 | 180 | +.integration-speechtotext .content-editor {  | 
 | 181 | +  width: 100%;  | 
 | 182 | +  overflow-y: auto;  | 
 | 183 | +  font-size: 14px;  | 
 | 184 | +  min-height: 20px;  | 
 | 185 | +  max-height: 150px;  | 
 | 186 | +  padding: 10px;  | 
 | 187 | +}  | 
 | 188 | + | 
 | 189 | +.integration-speechtotext .content-editor[contentEditable='true']:empty:before {  | 
 | 190 | +  content: attr(placeholder);  | 
 | 191 | +  color: #6b7280;  | 
 | 192 | +  font-style: italic;  | 
 | 193 | +}  | 
 | 194 | + | 
 | 195 | +.integration-speechtotext .option-container {  | 
 | 196 | +  align-self: flex-end;  | 
 | 197 | +}  | 
 | 198 | + | 
 | 199 | +{% endhighlight %}  | 
 | 200 | + | 
 | 201 | +{% endtabs %}  | 
 | 202 | + | 
 | 203 | +  | 
 | 204 | + | 
 | 205 | +## Error Handling  | 
 | 206 | + | 
 | 207 | +The `SpeechToText` component provides events to handle errors that may occur during speech recognition. For more information, refer to the [Error Handling](https://blazor.syncfusion.com/documentation/speech-to-text/speech-recognition#error-handling) section in the documentation.  | 
 | 208 | + | 
 | 209 | +## Browser Compatibility  | 
 | 210 | + | 
 | 211 | +The `SpeechToText` component relies on the [Speech Recognition API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition), which has limited browser support. Refer to the [Browser Compatibility](https://blazor.syncfusion.com/documentation/speech-to-text/speech-recognition#browser-support) section for detailed information.  | 
 | 212 | + | 
 | 213 | +## See Also  | 
 | 214 | + | 
 | 215 | +* [Messages](./messages)  | 
0 commit comments