How To

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!

Click to rate this post!
[Total: 11 Average: 4.5]
Dhiren Vasoya

Dhiren Vasoya is a Director and Co-founder at MageComp, Passionate ?️ Certified Magento Developer?‍?. He has more than 9 years of experience in Magento Development and completed 850+ projects to solve the most important E-commerce challenges. He is fond❤️ of coding and if he is not busy developing then you can find him at the cricket ground, hitting boundaries.?

View Comments

  • 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?

Recent Posts

Improving Error Handling and Transition Management in Remix with useRouteError and useViewTransitionState

In modern web development, seamless navigation and state management are crucial for delivering a smooth…

6 days ago

Magento Open Source 2.4.8-Beta Release Notes

Magento Open Source 2.4.8 beta version released on October  8, 2024. The latest release of…

1 week ago

How to Create Catalog Price Rule in Magento 2 Programmatically?

Hello Magento Friends, Creating catalog price rules programmatically in Magento 2 can be a valuable…

1 week ago

Top 10 Tips to Hire Shopify Developers

As the world of eCommerce continues to thrive, Shopify has become one of the most…

2 weeks ago

Managing Browser Events and Navigation in Shopify Remix: useBeforeUnload, useHref, and useLocation Hooks

Shopify Remix is an innovative framework that provides a streamlined experience for building fast, dynamic,…

2 weeks ago

Ultimate Guide to Hiring a Top Shopify Development Agency

Building a successful eCommerce store requires expertise, and for many businesses, Shopify has become the…

2 weeks ago