How to Implement Voice Search in Magento 2

How to Implement Voice Search in Magento 2

Hello Magento Friends,

In today’s blog, I am going to reveal How to Implement Voice Search in Magento 2.

Search is the most commonly used functionality of your website by visitors. If the user cannot find what they are looking for easily, they will get frustrated and leave the site. Along with making the search easy, it should be quick as well to not waste users’ time.

Let your customers swiftly look for products from your site by typing the first 3 letters of the product and get the relevant results without page refreshing. For that use Ajax Search for Magento 2.

Similarly, there are other ways to make the search functionality easy and quick. Include a voice search function in your Magento web store.

Benefits of Voice Search for Magento 2 Store:

Following people or conditions would depend on the voice search facility and find it essential for a better user experience.

  • People with disabilities cannot use a keyboard or mouse.
  • People with temporary limitations like broken arms or hands.
  • People with learning disabilities use voice instead of typing.
  • People who prefer voice instead of typing to make the task quicker.

Steps to Implement Voice Search in Magento 2:

Step 1: First you need to add the default.xml file in the following path

app\code\Vendor\Extension\view\frontend\layout

Then add the code as follows

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="top.search">
            <block name="top.search.voice.input"
                   template="Vendor_Extension::voice.phtml">
                <arguments>
                    <argument name="title" xsi:type="string" translate="true">Voice Search</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

Step 2: After then add voice.phtml in the following path

app\code\Vendor\Extension\view\frontend\templates\voice.phtml

And add code as given below

<?php $helper = $this->helper('Vendor\Extension\Helper\Data'); ?>
<button id="search-voice-input"
        class="action voice-input hidden"
        type="button"
        title="voice-command"
        data-mage-init='{
            "Vendor_Extension/js/voice-search":{
                "storeLocale": "<?= /* @noEscape */ $helper->getConvertedLocaleCode() ?>",
                "skipSuggestions": <?= /* @noEscape */ (int) 0 ?>
            }
        }'>
    <?= __("Voice Search"); ?>
</button>

Step 3: Next, add voice-search.js in the following path

app\code\Vendor\Extension\view\frontend\web\js\voice-search.js

Then include the code mentioned below

define([
    'jquery',
    'mage/translate',
    'Magento_Customer/js/customer-data',
    'jquery-ui-modules/widget'
], function ($, $t, customerData) {

    $.widget("magecomp.voiceSearch", {
        options: {
            searchInput: '#search',
            activeClass: 'recording active',
            storeLocale: 'en-US',
            skipSuggestions: 0,
        },

        recognition: null,
        active: false,

        _init: function () {
            if (('webkitSpeechRecognition' || 'SpeechRecognition') in window) {
                this._initVoiceSearch();
            }
        },

        _initVoiceSearch: function () {
            var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

            this.recognition = new SpeechRecognition();
            this.recognition.lang = this.options.storeLocale;

            this.recognition.onaudioend = this._onAudioEnd.bind(this);
            this.recognition.onaudiostart = this._onAudioStart.bind(this);
            this.recognition.onend = this._onEnd.bind(this);
            this.recognition.onerror = this._onError.bind(this);
            this.recognition.onnomatch = this._onNoMatch.bind(this);
            this.recognition.onresult = this._onResult.bind(this);
            this.recognition.onsoundend = this._onSoundEnd.bind(this);
            this.recognition.onsoundstart = this._onSoundStart.bind(this);
            this.recognition.onspeechend = this._onSpeechEnd.bind(this);
            this.recognition.onspeechstart = this._onSpeechStart.bind(this);
            this.recognition.onstart = this._onStart.bind(this);

            this.element.on({
                mousedown: this._onMouseDown.bind(this),
                click: this._onClick.bind(this),
                touchstart: this._onClick.bind(this),
            });

            $(this.element).removeClass('hidden');
        },

        _onMouseDown: function (event) {
            event.preventDefault(); // Prevent stealing focus to prevent issues with mageQuickSearch widget
        },

        _onClick: function (event) {
            this.active ? this.stopSpeechRecogniton() : this.startSpeechRecognition();
        },

        startSpeechRecognition: function () {
            this.recognition.start();
            this.active = true;
            $(this.element).addClass(this.options.activeClass);
        },

        stopSpeechRecogniton: function () {
            this.recognition.stop();
            this.active = false;
            $(this.element).removeClass(this.options.activeClass);
        },

        _onAudioEnd: function () {
            // Open for extension
        },

        _onAudioStart: function () {
            // Open for extension
        },

        _onEnd: function () {
            this.stopSpeechRecogniton();
        },

        _onError: function (event) {
            var message = this._getErrorMessage(event);

            this._addPageMessage(
                $t(message),
                'error'
            );
        },

        _onNoMatch: function (event) {
            this._addPageMessage(
                $t('Unable to recognise that phrase. Please try again.'),
                'warning'
            );
        },

        _onResult: function (event) {
            var last = event.results.length - 1,
                voiceInput = event.results[last][0].transcript;

            if (voiceInput) {
                this._searchVoiceInput(voiceInput);
            } else {
                this._onNoMatch(event);
            }
        },

        _onSoundEnd: function () {
            // Open for extension
        },

        _onSoundStart: function () {
            // Open for extension
        },

        _onSpeechEnd: function () {
            this.stopSpeechRecogniton();
        },

        _onSpeechStart: function () {
            // Open for extension
        },

        _onStart: function () {
            // Open for extension
        },

        _searchVoiceInput: function (voiceInput) {
            var $search = $(this.options.searchInput)

            $search.val(voiceInput);

            if (this.options.skipSuggestions) {
                $search.closest('form').submit();
            } else {
                $search.trigger('input');
            }
        },

        _getErrorMessage: function (event) {
            var errorCode = event.error,
                logError = false,
                message = '';

            switch (errorCode) {
                case 'no-speech':
                    message = 'No speech was detected.';
                    break;
                case 'not-allowed':
                    message = 'Unable to start voice search. Please check your browser permissions and allow this website to use the microphone.';
                    break;
                case 'language-not-supported':
                    message = 'Unfortunately, your language is not supported by speech to text services at this time.';
                    break;
                case 'aborted':
                    message = 'Voice capture has been aborted.';
                    break;
                case 'audio-capture':
                    message = 'Voice capture has failed.';
                    break;
                case 'network':
                    message = 'Network connectivity is required for voice input.';
                    break;
                default:
                    message = 'An error has occurred with the speech to text services.';
                    logError = true;
                    break;
            }

            if (logError && event.message) {
                console.error(event.message);
            }

            return message;
        },

        _addPageMessage: function (message, type) {
            var customerMessages = customerData.get('messages')() || {},
                messages = customerMessages.messages || [];

            messages.push({
               text: message,
               type: type
            });

            customerMessages.messages = messages;

            customerData.set('messages', customerMessages);
        }
    });

    return $.magecomp.voiceSearch;
});

Step 4:  Lastly, add Data.php in the following path

app\code\Vendor\Extension\Helper\Data.php

And add the below-mentioned code snippet

<?php
namespace Vendor\Extension\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Locale\Resolver as LocaleResolver;

class Data extends AbstractHelper
{

    public function __construct(
        Context $context,
        LocaleResolver $localeResolver
    ) {
        $this->localeResolver = $localeResolver;
        parent::__construct($context);
    }

    public function getConvertedLocaleCode(): string
    {
        return str_replace('_', '-', $this->getStoreLocale());
    }

    public function getStoreLocale(): string
    {
        return $this->localeResolver->getLocale();
    }
}

Conclusion:

As of now, you know How to Implement Voice Search in Magento 2 and execute it for your store. If you face any hardship while implementing the code, connect with me through the comment box. Share the tutorial with your friends to help them with voice search implementation. Stay updated with us for more!

Happy Coding!

Previous Article

Magento 2: Add Custom Message to Admin Sales Order View, Invoice, and Credit Memo

Next Article

How can the Default Quantity be Set to 1 (instead of 0) on the Product Page in Magento?

Write a Comment
  1. Hello Dhiren Vasoya thank you for your module. I have implemented it, and I got no errors thus I am assuming it is working however I cannot seem to find the voice search button anywhere, is there supposed to be a button? If not, how do you actually make use of the voice search?

Leave a Comment

Your email address will not be published. Required fields are marked *

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨