Skip Navigation
Updated
September 19, 2023

WooCommerce products are custom WordPress “posts” with custom fields. They are arranged using the “product categories” and “product tags” custom taxonomies. Here, we’ll show you how multilingual WooCommerce sites work and what your WooCommerce themes need to make them multilingual-ready.

On This Page:

How Multilingual WooCommerce Sites Work

When a site uses WPML, a language is assigned to every element of content. This means that each product, category, and tag will have a language attribute. Translations are saved in the database as separate products, linked together using WPML’s language table. Translated products share the same images and have their separate fields with texts in the right language.

An example of translations assigned to different elements of content

Site administrators can translate conveniently using WPML’s product translation table. This way, they can focus on translating the required texts, without having to worry about how translations are stored in the database.

Because translations are separated in the database, it’s also easy to display multilingual WooCommerce sites. In fact, if you use the WordPress and WooCommerce APIs, your theme may already be multilingual-ready. With a little testing and possibly small edits, you can achieve complete multilingual compatibility and enjoy new markets.

Required Plugins for Multilingual WooCommerce Sites

To run multilingual WooCommerce sites, the following plugins are needed:

WPML and all related plugins, including WooCommerce Multilingual, come with the Multilingual CMS account type.

Hard-Coded Texts in Templates

Your template files display a mix of product information and hard-coded texts. For example, most templates will include the product name and a “Buy” link. The product name comes from the database, so you don’t need to worry about translating it.

You should make sure that all hard-coded texts are translatable, using GetText.

Good

<p><?php _e('Similar products:', 'my-textdomain') ?></p><input type="button" name="buy-button" value="<?php esc_attr_e('Buy now!', 'my-textdomain') ?>" />

In the example below, “Similar products” and “Buy now!” are not wrapped in GetText calls.

Bad

<p><?php echo 'Similar products:'; ?></p>

<input type="button" name="buy-button" value="Buy now!" />

Good

<p><?php _e('Similar products:', 'my-textdomain') ?></p><input type="button" name="buy-button" value="<?php esc_attr_e('Buy now!', 'my-textdomain') ?>" />

Bad

<p><?php echo 'Similar products:'; ?></p><input type="button" name="buy-button" value="Buy now!" />

Similar products” and “Buy now!” are not wrapped in GetText calls.

GoodBad
<p><?php _e('Similar products:', 'my-textdomain') ?></p><input type="button" name="buy-button" value="<?php esc_attr_e('Buy now!', 'my-textdomain') ?>" /><p><?php echo 'Similar products:'; ?></p><input type="button" name="buy-button" value="Buy now!" />Similar products” and “Buy now!” are not wrapped in GetText calls.

Make sure that you use your theme’s textdomain for all GetText calls.

Hard-Coded WooCommerce Pages

Many e-commerce themes include special pages, like the Cart or Account pages. The theme often includes links to these pages, appearing on every page on the site.

If you use a WordPress menu for these links, you should be all set. WPML displays a different WordPress menu for each language, so the links to these ‘special pages’ will be different, per language. However, if you hard-code these links in template files, you need to allow WPML to replace the links, with links to these pages in the right language.

The right way to link to the special WooCommerce pages is by using the WordPress API functions and the WooCommerce page IDs. WooCommerce Multilingual filters call to get_option() with the WooCommerce page IDs. It will return the ID of the page in the current language.

Good

<a href="<?php echo get_permalink(get_option('woocommerce_shop_page_id')) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>
<a href="<?php echo get_permalink(wc_get_page_id('shop')) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>

The “shop” is the slug of the page in the default language.

Bad

<a href="<?php echo get_permalink(5) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>

The “shop page” ID is hard coded. It will be different for different sites and for different languages.

<a href="/shop"><?php _e('Shop page', 'my-textdomain') ?></a>

The “shop page” URL is hard coded. It will be different for different languages.

GoodBad
<a href="<?php echo get_permalink(get_option('woocommerce_shop_page_id')) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>

<a href="<?php echo get_permalink(wc_get_page_id('shop')) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>
The “shop” is the slug of the page in the default language.
<a href="<?php echo get_permalink(5) ?>"><?php _e('Shop page', 'my-textdomain') ?></a>
The “shop page” ID is hard coded. It will be different for different sites and for different languages.<a href="/shop"><?php _e('Shop page', 'my-textdomain') ?></a>The “shop page” URL is hard coded. It will be different for different languages.

Multilingual-Ready Product Listings

If you use the WooCommerce shortcodes to display the product listing, you are all set. WooCommerce will load the products in the correct language and display them.

If you prefer to load products manually, using your own code, make sure that you are using the WordPress API, or WooCommerce API calls. If you access the database directly, WPML will not filter your call and you will get a mix of all products in all languages.

Good

<?php $products = get_posts(array('post_type' => 'product', 'suppress_filters' => 0)); ?><?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
);
$products = new WP_Query( $args );
?>

Bad

<?php $products = get_posts(array('post_type' => 'product')); ?>

suppress_filters will be set to true by default, preventing language filtering.

$products = $wpdb->get_results($wpdb->prepare(“SELECT * FROM {$wpdb->posts} WHERE post_type='product' ORDER BY ID DESC LIMIT %d", 10));

WPML doesn’t filter low-level SQL queries. All products in all languages will be returned.

GoodBad
<?php $products = get_posts(array('post_type' => 'product', 'suppress_filters' => 0)); ?><?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
);
$products = new WP_Query( $args );
?>
<?php $products = get_posts(array('post_type' => 'product')); ?>
suppress_filters will be set to true by default, preventing language filtering.$products = $wpdb->get_results($wpdb->prepare(“SELECT * FROM {$wpdb->posts} WHERE post_type='product' ORDER BY ID DESC LIMIT %d", 10));
WPML doesn’t filter low-level SQL queries. All products in all languages will be returned.

Once you’ve loaded the right products, you don’t need to worry about languages when displaying them. Each product will come with its own custom fields, with information in the correct language.

Multilingual-Ready Product Templates

Since translations are stored in separate products, displaying a single product on a multilingual WooCommerce site shouldn’t require special effort.

Multi-Currency Payment Options

Your multilingual WooCommerce site may also include multiple currencies. For many non-American sites, supporting multiple currencies is a very important feature. For example, many European sites will need to charge in Euros, British Pounds, and US Dollars. Eastern European sites often require Russian ruble while Asian sites need a variety of different other currencies.

Multi-currency support is included in WooCommerce Multilingual. To allow visitors to switch between currencies, your theme should include an optional currency switcher.

You can display a currency switcher either by using a PHP call or by inserting a shortcode.

<?php do_action('currency_switcher', array('format' => '%name (%symbol)')); ?>
[currency_switcher]

For more information, see the tutorial on multi-currency for WooCommerce. Please note that you will only see the currency switcher on the front-end if the site uses multiple currencies.

Making Your WooCommerce Site RTL Compatible

WooCommerce themes need to follow the same RTL themes support guidelines as any other WordPress themes. You should create an rtl.css file, with the CSS rules for RTL display.

Handling Different Text Lengths in Different Languages Using Fluid Design

When you create your multilingual-ready WooCommerce theme, remember that some texts will be longer in certain languages and shorter in others. Sometimes, you will not even be able to test, because your end-users will translate.

For example, look at these two product blocks.

CSS optimized for short text in English

Longer Spanish texts don’t fit the space

As a rule of thumb, test your theme with texts that are x2 longer and ½ shorter. This will cover you in most cases. The best way to handle texts of different size is by allowing for fluid layouts. Fluid layouts will allow elements to resize and capture the area that they need. Creating an elegant template with fluid sizes isn’t trivial, but doing so helps avoid visual glitches

Text overflows nicely from line to line with no display glitch

Ready to Get Started?

If you are a developer, building WooCommerce themes or extensions, you should definitely join our Go Global program. You will receive a complementary WPML developer account and get priority support from our compatibility team. The WooCommerce shop is only one (big) section of your theme. You should definitely read our guide on achieving WPML compatibility for your themes.

Building sites for clients? Buy WPML and get started with multilingual sites for WooCommerce and beyond.