Skip to content

Hiding country specific navigation URLs using Shopify Markets and qikify Smart Menu

Internationalisation is an incredibly important part of SEO, and Shopify Markets is one of the quickest ways to implement it effectively. That said, it is not without its limitations.

Here is a recent example that had us scratching our heads. A client has several international stores, but not all products and categories are available in each country. 

The problem arose when a specific product is available in the UK and EU but not in the US. This site uses the qikify Smart Menu to build the main navigation, and the product was displayed in the menu on the US store, leading to a 404 error if customers clicked on it. 

Unfortunately, the app doesn’t provide a way to specify menus for specific stores. So, what can be done?

Initially, using CSS to hide the item seemed like a solution, but it wasn’t possible to target the specific menu item as the app didn’t allow assigning custom classes or IDs. 

As a result, JavaScript was employed to target the menu, find the link associated with the product, and hide it by removing it from the DOM. However, it became more complex as the menu item didn’t exist in the DOM until the user hovered over the menu. 

To address these challenges, the following solution was implemented:

First, information about the store needed to be obtained and used in JavaScript. To achieve this, a <div class=”route”>{{ routes.root_url }}</div> element was added to the theme.liquid file at the top of the body tag. The CSS was modified to set the route class to display:none; to hide it from view.

The purpose of the added div element was to store the country of the store. For example, if browsing the default store (US), the content would be /, and if switching to the UK store, it would show /en-gb.

Next, a JavaScript file was created, and the initial script was added to make it work:

function alter_menu() {



  // Get the text content of the element with the class "route"

  let { textContent: strippedRoute } = document.querySelector('.route');



  // Remove the slash if the root url is empty

  if (strippedRoute === '/') {

    strippedRoute = '';

  }



  // Check if the strippedRoute is empty

  if (strippedRoute === '') {

    // Call the alter_menu_action function

    alter_menu_action();

  }


}

 

This script retrieves the content of the route element we created earlier. If the content is not empty (indicating it’s not the US store), it calls another function. It can be adapted to call different scripts based on individual stores.

The main script is as follows:

function alter_menu_action() {




    // Function to execute on 'mouseover'

    let mouseOverFunc = () => {

        setTimeout(() => {

            // Find the megaMenu element with an ID containing "qikify-tmenu-megamenu-3"

            const megaMenu = document.querySelector('[id*="qikify-tmenu-megamenu-3"]');

            if (megaMenu) {

                // Find the targetLink element with an anchor tag and "href" containing "form"

                const targetLink = megaMenu.querySelector('a[href*="product3"]');

                if (targetLink) {

                    // Find the closest ancestor li element of targetLink

                    let parentLi = targetLink.closest('li');

                    if (parentLi) {

                        // Remove the parentLi element from its parent node

                        parentLi.parentNode.removeChild(parentLi);

                    }

                }

            }

            // Disconnect the observer to stop observing mutations

            observer.disconnect();

            // Remove event listeners

            removeEventListeners();

        }, 0);

    };




    // Function to remove event listeners from elements

    let removeEventListeners = () => {

        // Select all elements with the class "tmenu_item_submenu_type_mega"

        let liElements = document.querySelectorAll('.tmenu_item_submenu_type_mega');

        liElements.forEach(li => {

            // Remove the 'mouseover' event listener from the li element

            li.removeEventListener('mouseover', mouseOverFunc);

            // Remove the 'mouseover' event listener from all descendants of the li element

            Array.from(li.querySelectorAll('*')).forEach(child => {

                child.removeEventListener('mouseover', mouseOverFunc);

            });

        });

    };




    // Create a new MutationObserver to observe mutations on the document and its descendants

    let observer = new MutationObserver(() => {

        // Select all elements with the class "tmenu_item_submenu_type_mega"

        let liElements = document.querySelectorAll('.tmenu_item_submenu_type_mega');

        liElements.forEach(li => {

            // Remove the 'mouseover' event listener from the li element

            li.removeEventListener('mouseover', mouseOverFunc);

            // Add the 'mouseover' event listener to the li element

            li.addEventListener('mouseover', mouseOverFunc);

            // Remove the 'mouseover' event listener from all descendants of the li element

            Array.from(li.querySelectorAll('*')).forEach(child => {

                child.removeEventListener('mouseover', mouseOverFunc);

                // Add the 'mouseover' event listener to all descendants of the li element

                child.addEventListener('mouseover', mouseOverFunc);

            });

        });

    });




    // Start observing mutations on the document and its descendants

    observer.observe(document, { childList: true, subtree: true });

  

}



 

This script is triggered by a mouseover event. It looks for the menu in the DOM with an ID containing “qikify-tmenu-megamenu-3”. Once found, it searches for the anchor element (link) with an “href” containing “product3”. Upon finding it, it identifies the closest ancestor <li> element and removes it from the DOM.

For reference, imagine the megamenu code is structured as follows:

<ul id= “qikify-tmenu-megamenu-3”>

<li><a href=”/product1”>product 1</a></li>

<li><a href=”/product2”>product 2</a></li>

<li><a href=”/product3”>product 3</a></li>

</ul>

 

After performing this action, additional code is included to remove the event listeners from the page. This ensures that the script runs only once upon the first mouseover and doesn’t execute repeatedly.

Our final task is to add the following to the bottom of theme.liquid:

  <script>

    alter_menu();

  </script>

 

Get in touch

Have a problem that Blink can help with? Let us know more about your project below and we’ll be in contact as soon as we can.