Multi-Language Shopify Online Shop

A guide to create a multi-language, multi-currency Shopify online shop without a third-party app.

Shopify is a brilliant e-commerce platform but natively Shopify supports only 1 language per shop. In this guide I show you some hints to create a multi-language online shop with Shopify. In addition I created a multi-language demo store. Feel free to download the sources from my public Github repository.

The Shopify Theme Editor is an awesome tool but for multi-language support you have to create a custom theme using HTML and Liquid.

Multi-Language Hints

Alternate Templates

Shopify allows you to create alternate templates for your various page types — for instance if you have a default product template you can create an additional product.pre-order template for products not available yet.

I use this mechanism to create language versions for my templates. For instance index.liquid is the default English homepage version and is the German homepage version.

To access the alternate language version append the URL parameter view=suffix (e.g. view=de).

Homepage EN:
Homepage DE:
Product EN:
Product DE:

Within your template or layout file you have access to the template.suffix variable.

{% if template.suffix == 'de %}
// German content
{% endif %}

I use this variable to include the correct navigation menu snippet for the current language (nav.liquid for English and navde.liquid for German) in the theme.liquid layout file:

<!DOCTYPE html>
{% assign navbar = ‘nav’ | append:template.suffix %}
{% include navbar %}
        {{ content_for_layout }}

Instead of the standard theme.liquid layout you can also create a separate layout for you language variation using the Liquid layout tag in the alternate template.

// E.g. template
{% layout 'theme-de' %}

Unfortunately HTML form submits on the shopping cart do not support the view parameter for alternate templates. This means you have to use JavaScript for your add, update, delete actions. Here an example from the product page that adds an item to the cart.

<form action="/cart/add" method="post">
<input type="hidden" name="id"
value="{{ }}">
<input type="submit" class="btn" value="In den Warenkorb">
$(document).ready(function() {
$('form[action="/cart/add"]').on('submit', function(e) {
            var data = $(e.currentTarget).serialize();
$.post('/cart/add.js', data, function() {
window.location.href = "/cart?view=de";


Currency Conversion

Shopify hosts a JavaScript tool for currency conversions that is updated 3 times a day.

List of products displaying the price in USD and EUR

In the Shopify general settings you configure a default currency. Even if you convert the prices in your templates to a different currency, during checkout you will always see the prices in the default currency.

Therefore I always show the converted price next to the price in the default currency — e.g. $6.00 (€5.64).

To keep it simple I convert the currencies in the demo store only from USD to EUR. I use this HTML to display the price:

<span class=”price”>{{ product.price | money }}</span>
<small class=”text-muted ml-2 euro”></small>
{% include 'currencies' %}

The currencies snippet first includes the Shopify currencies JavaScript. For each element with the class “price” it extracts the USD price in its smallest unit (cents) via regex. Then convert the USD value to EUR and append the result to the next available element with the class “euro”.

{{ "//" | script_tag }}
$(document).ready(function() {
$('.price').each(function() {
var el = $(this);
            var dollar = el.text().replace(/^\D+/g, '');
var euro = Currency.convert(dollar, 'USD', 'EUR')
.toFixed(2);'.euro').text('(€' + euro + ')');

Product Title and Description

The product title and description has a huge impact on multi-language translations because this text is displayed in many different places — e.g. templates, checkout, notification emails. There is no perfect solution but you can choose between 2 workarounds.

  1. Duplicate all products in all languages
  2. Use single products with multi-language text (e.g. lang1 / lang2 / lang3) and translate texts via JavaScript where possible

Duplicate Products

The big advantage of this method is that the translated title and description is used on all places: templates, collections, checkout, notification. In combination with alternate templates (separate URLs for each language) you have full control over your SEO and social media tags.

Downside is that you have to manage many more product items in the store. (e.g. if you have 50 products and 5 different languages results in 250 product items to manage). In addition it is more difficult to track inventory. Anyway in the demo store I used this method.

Duplicate products in English and German

Single Product — Translation via JavaScript

This is more complex and I assume it is the way some of the Shopify translation apps work. Usually the text is not maintained via the Shopify administration interface but instead within a separate Shopify app or other resource (JavaScript, JSON file).

In the demo store I created a sample page that works with a simple JavaScript for language translations.

On the template page I added extra data for identifying the product, language, key to translate:

<h2 class=”translate” 
data-id=”{{ handle }}”
data-key=”title”>{{ product.title }}</h2>

The JavaScript simply iterates over all elements with the class translate gets the value of the data attributes lang, id, key and uses the information to lookup the translation from the data object. Of course the data object is usually maintained on a different place (e.g. Shopify app, custom server, JSON file) but for the demo it is sufficient.

$(document).ready(function() {
var data = {
de: {
"red-circle": {
title: "Roter Kreis",
description: "Beschreibung roter Kreis"
// TBD
en: {
// TBD
        $('.translate').each(function() {
var el = $(this);
            var lang ='lang');
var id ='id');
var key ='key');
            if (lang && id && key) {

Proceed to Checkout

The whole checkout process is controlled by Shopify and usually uses the language configured in the admin panel.

German cart page

On the cart page you can pass a locale parameter to the checkout action to control the language during checkout.

<form class="form" action="/checkout?locale=de" method="POST">
<input type="hidden" name="attributes[Locale]" value="de">
    <a href="/?view=de">Weiter Einkaufen</a>
<input type="submit" name="checkout" value="Zur Kasse">

It is important that you add the locale parameter to the action attribute and that the form method is POST.

<input type="hidden" name="attributes[Locale]" value="de">

In addition I added a custom cart attribute with the name Locale that is passed through the checkout and shows up on the order detail page.

Shopify order detail page with custom cart attribute Locale

This information shows me which language the customer used during checkout and I can use this value in the notification email templates.

On the checkout page there is one last issue. The name of the shipping method cannot be translated. But you can create separate shipping zones for countries with the same language. These zones you name in the local language. E.g. a standard shipping for German speaking countries is named “Standardversand”.

Notification Emails

Notification emails are configured in the “Settings/Notifications” section of the Shopify admin panel. As outlined in the previous section you can add a custom cart attribute (e.g. Locale) to the checkout that stores the user’s language during checkout. This attribute is available as variable in all email templates that contain the order properties.

For the demo store I translated the order confirmation email only. I use the framework to create pretty responsive emails.

In the subject line you have access to the attributes variable as well:

{% if attributes.Locale == 'de' %}Bestellung {{name}} bestätigt{% else %}Order {{name}} confirmed{% endif %}

If you use for your emails be sure to write the Liquid if statements within the <mj-text> element otherwise they will be ignored.

{% if attributes.Locale == 'de' %}
<h3>Vielen Dank für Deinen Einkauf!</h3>
Hallo {{ customer.first_name }},
wir bereiten Deine Bestellung für den Versand vor.
Wir benachrichtigen Dich sobald sie unterwegs ist.
{% else %}
<h3>Thank you for your purchase!</h3>
Hi {{ customer.first_name }},
we're getting your order ready to be shipped.
We will notify you when it has been sent.
{% endif %}
Order confirmation after German checkout


I’m aware that there are many more options available how to support multiple languages in Shopify. This is just a collection of my findings during my last project. Feel free to add your ideas in the comments below.

Demo Store

To demonstrate how a multi-language Shopify shop works I created a demo store and published the resources on my Github repository. Here you find a step by step introduction how to get there.

Step 1: Setup Shopify Shop

Shopify offers the option to either start a 14-days trial from their homepage or you join the free Shopify partner program where you are able to setup demo stores for theme and app development.

After you created the store add some products. For the demo store I added the virtual products circle and square in the colors red and blue.

Virtual products for my demo store

Enter some basic configuration and the store is ready to try out. The demo store (screenshots below) is created using the Shopify Theme Editor.

Demo store created with Theme Editor

Step 2: HTML Version of a Custom Theme

I created a very simple HTML version using the Bootstrap CSS framework. You find the sources in the theme-html of my Github repository.

Just download the repository as ZIP and open the index.html file in your browser.
Custom theme with Bootstrap

Step 3: Transform HTML Version to Shopify Theme

Then I created Liquid templates from the HTML version. You find the sources in the theme-simple subdirectory in the Github repository.

Step 4: Add Multi-Language and Multi-Currency Support

As last step I added multi-language support using the hints I outlined in the previous section. You find the sources in the theme-multi-lang and notification-emails subdirectory of the Github repository.

My Wishlist to Shopify

Shopify is extremely powerful but on the other hand very simple and intuitive to use. Exactly this is what we all love about this platform. Adding full multi-language and multi-currency support would result in adding enormous complexity. I understand that Shopify is very careful with this. Anyway there are some small improvements that would help anyone creating his own multi-language online shop.

Link to a language version of the order_status_url page

In the notification email I’d like to link to the order status page. Unfortunately I’m not able to add a locale parameter to the link.

{{ order_status_url | locale: 'de' }}

View alternate template after form submit

Especially when interacting with the shopping cart (add, update, remove) I have to use JavaScript. I’d rather like to use standard HTML form submits and can include a hidden parameter to redirect back to my original alternate cart view.

<form action="/cart/add" method="post">
<input type="hidden" name="view" value="de">

Maintain Sitemap XML to Include Alternate Templates

The sitemap XML is created automatically which is absolutely fine. But I’m not able to include the alternate templates. A solution for this problem would be perfect.

Native Support for Multiple Languages and Multiple Currencies

All the hints I described in my article are workarounds. I know this is a huge challenge but adding native support for multiple languages and multiple currencies would be the best solution for the customers. Anyway, congratulations to the Shopify team that you created such a brilliant product.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.