Integrate your Country Selector

This documentation is for developers only. If you're not a developer, please send this information to your developer, as they can follow the documentation.

We always recommend using our "Market Selector" app embeds. This article is only for synchronizing your native theme country selector.

If you have more than one store synced with Orbe, please don't follow this article. Your selector should be the one created by the Orbe app.

If you need any customization for this selector, please get in touch with our Support team via app chat or email at support@orbe.app.

In our app Orbe, we have an app embed called "Market Selector" that allows any Shopify merchant to add and customize a country and language selector in the footer of any Shopify Theme. These selectors use the Orbe technology.

However, some merchants would like to use their native Shopify theme country and language selector with Orbe because they want its style and UX in their theme. They can work with a developer to synchronize this theme selector with Orbe for that case.

Tutorial

This tutorial provides a straightforward and effective method for integrating a country selector with Orbe, ensuring a seamless user experience.

1. Step 1: Retrieve the store domain

First, ensure we correctly set cookies across your Shopify store by capturing the domain.

This can be achieved using Orbe's getCountryDomain function. If this function does not provide a result, we'll use window.location.hostname as a reliable fallback.

let shopDomain = orbito.getCountryDomain ? orbito.getCountryDomain() : window.location.hostname;

2. Customize the onItemClick Event handler

Locate the function in your Shopify theme that triggers when a user selects a country. This function usually handles the event and submits the form in the last step.

Here you have an example of which would be the code from the country selector of the official Shopify documentation:

onItemClick(event) {
    event.preventDefault();
    const form = this.querySelector('form');
    this.elements.input.value = event.currentTarget.dataset.value;
    if (form) form.submit();
}

Here, we'll ensure the country parameter is added or updated in the return_to input without altering any other URL components.:

onItemClick(event) {
  event.preventDefault();
  const form = this.querySelector('form');
  
  // Get the return_to
  const returnToInput = form.querySelector("input[name='return_to']");
  
  // Check if the 'country' parameter already exists and if not add it to the URL
  if (returnToInput.value.match(/(\?|&)country=[^&]*/)) {
    // Replace the existing country parameter
    returnToInput.value = returnToInput.value.replace(/(\?|&)country=[^&]*/, '$1country=' + countryCode);
  } else {
    // Add the country parameter
    if (returnToInput.value.includes('?')) {
      returnToInput.value += '&country=' + countryCode;
    } else {
      returnToInput.value += '?country=' + countryCode;
    }
  }

  // Update the saved Orbe cookie
  document.cookie = `mdApp_countryCodeDomain=${countryCode}; domain=${shopDomain}; path=/; max-age=${60 * 60 * 24 * 60};`;

  // Update the form's input field for country code and submit the form
  this.elements.input.value = countryCode;
  if (form) form.submit();
}

Real example

Here is an example of how the entire code might look, based on the JavaScript for the official Shopify country selector documentation:

class LocalizationForm extends HTMLElement {
  constructor() {
    super();
    this.elements = {
      input: this.querySelector('input[name="language_code"], input[name="country_code"]'),
      button: this.querySelector('button'),
      panel: this.querySelector('ul'),
    };
    this.elements.button.addEventListener('click', this.openSelector.bind(this));
    this.elements.button.addEventListener('focusout', this.closeSelector.bind(this));
    this.addEventListener('keyup', this.onContainerKeyUp.bind(this));

    this.querySelectorAll('a').forEach(item => item.addEventListener('click', this.onItemClick.bind(this)));
  }

  hidePanel() {
    this.elements.button.setAttribute('aria-expanded', 'false');
    this.elements.panel.setAttribute('hidden', true);
  }

  onContainerKeyUp(event) {
    if (event.code.toUpperCase() !== 'ESCAPE') return;

    this.hidePanel();
    this.elements.button.focus();
  }

  onItemClick(event) {
    event.preventDefault();
    const form = this.querySelector('form');
    const input = event.currentTarget.dataset.input;
    const value = event.currentTarget.dataset.value;

    if (input === "country_code") {
      // Specific logic for country code
      const returnToInput = form.querySelector("input[name='return_to']");
      // Check if the 'country' parameter already exists
      if (returnToInput.value.match(/(\?|&)country=[^&]*/)) {
        // Replace the existing country parameter
        returnToInput.value = returnToInput.value.replace(/(\?|&)country=[^&]*/, '$1country=' + value);
      } else {
        // Add the country parameter
        let existingParams = returnToInput.value.includes('?') ? '&' : '?';
        returnToInput.value += `${existingParams}country=${value}`;
      }

      // Set the cookie for the country code
      document.cookie = `mdApp_countryCodeDomain=${value}; domain=${shopDomain}; path=/; max-age=${60 * 60 * 24 * 60};`;
    }
    
    // Update the input value and submit the form
    this.elements.input.value = value;
    if (form) form.submit();
  }

  openSelector() {
    this.elements.button.focus();
    this.elements.panel.toggleAttribute('hidden');
    this.elements.button.setAttribute('aria-expanded', (this.elements.button.getAttribute('aria-expanded') === 'false').toString());
  }

  closeSelector(event) {
    const shouldClose = event.relatedTarget && event.relatedTarget.nodeName === 'BUTTON';
    if (event.relatedTarget === null || shouldClose) {
      this.hidePanel();
    }
  }
}

customElements.define('localization-form', LocalizationForm);

Last updated