top of page


Real Time Voice to Text Search With Velo and Speechly

Wed Feb 09 2022



  • Twitter
  • Black LinkedIn Icon
  • Facebook

Voice interaction with our devices has evolved and is becoming an expected standard feature. Your users want to be able to get what they...

Voice interaction with our devices has evolved and is becoming an expected standard feature. Your users want to be able to get what they need quickly in a natural and convenient way. In part 1 of this 2 part series you will learn how to implement a voice search bar in your Velo enabled site using Speechly. When complete, you will have created a custom element that lets your users sort through blog posts using text input or voice.

To begin you will need to make sure your site is on a Wix Premium plan and has a connected domain with ads removed.

Introducing Speechly

Founded in 2016, Speechly was born out of the simple idea that voice powered UX can and should be much better. What Speechly brings to this space is the ability to extract the intentions of the user into useful data without forcing users to alter the way they naturally speak. Speechly’s team of experts accomplished this with proprietary Spoken Language Understanding® technology that is able to map speech to intents in real-time, as users speak. This means that users can see their words instantly generate reactions within the visual element. In the following you will learn how to implement custom search using their push to talk button UI component.

To see Speechly in action and learn more about what you can do with their voice tools, check out their demos.

How can I use Speechly in my Velo site?

Speechly offers beautiful out of the box UI components that can be easily integrated into your site today using custom elements in Velo. For the more advanced user, they also offer highly customizable and reactive voice processing driven by configurable machine learning algorithms right from their dashboard. In part 2 of this series you will add a Speechly Velo package to your Wix Stores site to implement a custom shopping experience.

Adding voice search to Velo

Prerequisites: This solution requires a premium site with a connected domain and dev mode turned on.

Overview: This tutorial will cover adding a custom element to your Velo site that will integrate Speechly with the Wix Search API and display the results in a repeater. This example will focus on a search for blog posts, but the functionality can be applied to any document type, such as Products or site pages.

Note: This tutorial assumes familiarity with dev mode and some JavaScript knowledge. For more information about coding in Velo, visit the learning center.

Relevant Documentation:

Steps to implement the custom search:

  • Open the editor and turn on dev mode.

  • Add the Wix Site Search App to enable the Wix Search API. This will also automatically add a site search bar to your top navigation and a search results page to your Velo site. If you do not want a full site search available simply delete the search bar that was added. The results page will still exist, but without the search bar a user will not end up being routed to this page.

  • Add the Wix Blog App to your site. This will come pre-populated with some blog entries.

  • Add a repeater to your site and connect the data from the blog collection.

  • Connect the data from the Blog Posts collection to your respective repeater fields.

  • Name the elements as follows by clicking on each element within the repeater and updating the ID name in the Properties and Events panel. You may also choose your own element names. If you decide to use your own names, you must update the names in the code in Step 3 under Hooking up the Page Elements.

Repeater Elements:

repeater shown in the editor with fields highlighted to show the ID names

Hover elements:

Repeater in the editor with hover tab active and a Read More button highlighted to show the ID

Properties and Elements Panel where the ID can be updated:

Properties and Events Panel open with tags filled in the ID field

  • On the left hand menu, click { } to open your code files.

  • Under Public create a folder called custom-elements. This path is important to linking your file to the custom UI element.

  • In the custom-elements folder create a javascript file and name it anything you like.

  • Create a style function and add search bar styles.

const createStyle = () => {
  const styleElement = document.createElement('style');
  styleElement.innerHTML = `
  main {
     display: flex;
     flex-direction: row; justify-content: center;
     align-items: center;
     min-height: 25vh;
     margin: 0;
     padding: 0;

  .group {
     margin: 0 0 3rem 0;

 input {
   font-size: 1.5rem;
   border: 1px solid #ccc;
   padding: 0.5em;
   border-radius: 30em;
   background-color: #fff;

 input:focus {
   outline: none !important;
   box-shadow: 0 0 10px #fff;

 ::placeholder {
   color: #aaa;
   opacity: 1;

 .inputContainer {
   position: relative;

.startAdornment {
   position: absolute;
   left: 0;
   top: 0;
  bottom: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  color: #aaa;
  padding: 0.5rem;
  font-size: 1.75rem;

 .endAdornment {
   position: absolute;
   right: 0.3rem;
   top: 0;
   bottom: 0;
   display: flex;
   flex-direction: row;
   justify-content: center;
   align-items: center;
   color: #aaa;
   padding: 0rem;

 svg {
   fill: currentColor;

 #searchBox {
   box-sizing: border-box;
   width: 60vw;
   min-width: 16rem;
   max-width: 36rem;
   padding-left: 3rem;

  return styleElement;

  • Add a function for the Speechly UI web component.

const createInputElement = () => {
const div = document.createElement('main');
const html =  `<div class="group">
        <div class="inputContainer">
          <input id="searchBox" type="text" placeholder="Search with voice..." autofocus>
          <div class="startAdornment">🔍</div>
          <push-to-talk-button size="2.8rem" class="endAdornment" fontsize="0.90rem" backgroundcolor="#104864" intro="Tap or hold for voice search" showtime="30000" appid="YOUR_SPEECHLY_APP_ID"/>
  div.innerHTML = html;
  return div;

Add the custom class and callback.

class CustomVoiceSearch extends HTMLElement {

connectedCallback() {


   .addEventListener("speechsegment", (e) => {
   const segment = e.detail;
   document.getElementById("searchBox").value = segment.words.filter(w => w.value).map(w => 
   w.value.toLowerCase()).join(" ");
   this.dispatchEvent(new CustomEvent('get-new-input', {  detail:     document.getElementById("searchBox").value }));

document.getElementById("searchBox").addEventListener("input", (e) => {
   this.dispatchEvent(new CustomEvent('get-new-input', {  detail: document.getElementById("searchBox").value }));


customElements.define('custom-voice-search',  CustomVoiceSearch);

Code Details: In the callback code above you are adding the styles and the Speechly web component and then adding some event listeners to wait for changes from either user input or voice input. When the user types or speaks into search, you are sending that information to your page code through dispatchEvent(). The dispatch event is placed inside the listener so that the code will update in real time with each word the user inputs or utters.

Note: To create your own AppID in Speechly, review their guide. This AppID should be stored in the Secrets Manager. If you are unfamiliar with using the Secrets Manager, learn how to set up new secrets here.

Hooking up the Page Elements

Now that your custom element code is ready, you can add it to your page.

  • Add a custom embed element and in the settings select Velo file. You should see the JS file you just created. In the tag name field, add your custom tag name from the component you just created. In the example above, the tag name is 'custom-voice-search'.

  • In the page code, import the Wix Search API:

	  	import wixSearch from "wix-search";
  • In your onReady function, add the following code. Note that you may need to change the id names based on your own naming conventions.

$w.onReady(function () {
//prepare the empty data array for the repeater results
 $w("#searchResults").data = [];
//listen for the dispatched event and get the input value
 $w("#customSearch").on("get-new-input", (e) => {
   let searchValue =;
   if (e.detail.length > 0) {
 //set the document type here to whatever type of document you are searching
       .then((results) => {
         if (results.documents.length > 0) {
           $w("#searchResults").data = results.documents;
         } else {
           console.log("No matching results");
       .catch((error) => {
   } else {
//if the user clears the search input, reset to the all posts list
     $w("#searchResults").data = [];

Populate the repeater.
$w("#searchResults").onItemReady(($item, itemData) => {
   $item("#title").text = itemData.title;
   $item("#tags").text = itemData.tags[0];
   $item("#description").text = itemData.description.substring(0, 100) + "...";
   $item("#image2").src = itemData.image;
   $item("#button3").link = itemData.url;
  • In the dashboard, add the Speechly header script in Settings > Custom Code:

<script type="text/javascript" src=""></script> 
  • Click Publish and test out your new voice search. Note that Speechly will not initiate in preview mode so you must test this from a published site.

Now that you have created the custom element, you can integrate this feature anywhere on your site to give users the option to search through posts, pages, or products with their voice.

If you would like some more information or want to see the setup in action, this tutorial is also available in video format.



get certified.png

Related Posts

View All



Velo monthly roundup: June

Velo monthly roundup: June

Tue Aug 01 2023



Velo monthly roundup: May

Velo monthly roundup: May

Fri Jun 02 2023



Velo monthly roundup: March

Velo monthly roundup: March

Mon Mar 20 2023

bottom of page