Skip Navigation
November 15, 2023

Every WordPress theme and plugin can become compatible with WPML.

Follow this tutorial to learn how to test WPML compatibility and make the required changes to make your code fully multilingual-ready.

Theme and Plugin Authors

Join our Go Global program and make your plugins and themes WPML Compatible.

On This Page:

  1. Installing WPML Components
  2. Case Study – Sydney Theme
  3. Translating the Header
  4. Translating Menus
  5. Translating Sydney Theme’s Services and Other Custom Post Types
  6. Translating Theme or Plugin Custom Elements
  7. Translating the Post Body
  8. Translating WordPress Widgets
  9. Translating the Footer
  10. Hiding the Language Switcher from the Settings Page
  11. Creating a Language Configuration File for Your Theme
  12. GetText Support for Hard-Coded Strings
  13. WooCommerce Compatibility
  14. Making Custom Elementor Widgets and Other Page Builder Widgets Translation-Ready
  15. Tips and Debugging

Important: Remember to Include a Language Configuration File

When you are done, you need to create an XML language configuration file and add it to your theme’s root directory.

This will allow end-users to run multilingual sites with your theme, without having to configure anything themselves.

Without such a language configuration file, your end-users will waste hours trying to reverse engineer your design and guess which texts require translation. This leads to more support work for you and for us. If you need help creating a language configuration file, tell our theme compatibility team and they will assist you.

1. Installing WPML Components

WPML includes several components. Some are required for your theme compatibility work and some are intended for site admins, who will later manage the site’s content.

You should activate the essential WPML components, which will allow you to fully translate your theme:

  • WPML core plugin
  • WPML String Translation add-on

To get them, go to your WPML account and click on Downloads.

Of course, you are welcome to learn about the other components in WPML core and addons.

2. Case Study – Sydney Theme

Let’s look at this example of a website created with the Sydney theme, from aThemes:

Sydney website example
Example of a website built using the Sydney theme

As we go through the different elements in this site, we’ll learn how to translate rich themes or plugins with WPML.

3. Translating the Header

The theme’s or plugin’s header comes from the WordPress general settings as displayed in the following image:

WordPress General Settings page

Since it’s not part of any post, we need to use WPML’s String Translation to translate it. Go to the WPML String Translation page, search for the string by its content (i.e. “Site’s title”) and translate it.

Translating other texts coming from the theme and plugins using WPML’s String Translation page

You don’t need to do anything in the theme or plugin to make this happen. WPML handles it automatically. We showed how to translate the site name because we are going to use WPML’s String Translation for many other elements in your theme or plugin.

4. Translating Menus

WPML translates WordPress menus without you needing to do anything. As long as your theme uses the standard WordPress menu system, WPML will translate the menus.

Menu translation controls
Automatic translation of menus that use the standard WordPress menu system

When you go to the Appearance Menus page, you will see WPML’s menu translation controls. Learn more about translating menus to see how this works.

5. Translating Sydney Theme’s Services and Other Custom Post Types

The example theme that we are looking at uses a custom post type, “Services”. It is easy to translate it using WPML, with little configuration. It also applies to the “Testimonials”, “Clients”, and “Projects” post types.

We need to tell WPML that the “Services” custom post type is multilingual. This means that WPML offers users to translate it.

WPML allows three modes for translatable content:

  • Translatable, only show translated items
  • Translatable, use translation if available or fallback to default language
  • Not translatable

This gives you great flexibility in deciding what content gets translated and how the translations are displayed (or not).

We want to translate the “Services”, so we can show our offer in different languages.

Navigate to WPMLSettings and scroll down to the Post Types Translation. Select one of two Translatable options in the row(s) for the custom post types you want to be translatable and then Save.

Choosing which custom post types you want to be translatable

6. Translating Theme or Plugin Custom Elements

Many themes and plugins have unique features which store texts in the wp_options table. The slide captions feature, by Sydney, does that exactly.

Translating texts featured in the wp_options table

The theme or plugin saves these texts in the wp_options table and we need to tell WPML to translate them. We add this information to the Language Configuration File. There, we tell WPML which entries in the wp_options table require translation.

This technique is good when the keys for the options are fixed (like in most themes). If your theme uses an array of entries – which may grow with user input – you need to register these entries dynamically. Use WPML’s API functions to do this.

6.1 Adding Your Plugin’s Translations

To add translations to your plugin, we recommend creating a languages folder inside your plugin’s main folder and placing all your .mo files there.

Then, WordPress needs to load and associate them correctly with your plugin’s Text Domain. In order to do so, you need to call them with a load_plugin_textdomain function right after the header of your theme/plugin file. This code should be placed in a file located within the root folder of your plugin:

7. Translating the Post Body

WPML lets users translate content with ease. The post-edit screens include WPML’s translation controls, allowing to create new translations and edit existing ones.

Translating a post from the post editor

You don’t need to do anything in the theme or plugin to make this happen. Translating content is a core feature of WPML.

What you do need to check is that any text that your theme adds to the output is translatable. For example, the highlighted texts in this screenshot should be wrapped in gettext calls.

Theme texts
Ensuring text that your theme adds to the output is translatable

If you’re new to using gettext, learn more about it in our theme texts translation FAQ.

8. Translating WordPress Widgets

WPML lets users translate the content of text widgets. It also translates titles of all other widgets. If your theme or plugin creates its own custom WordPress widgets, make sure that you pass their titles through the standard WordPress filters. The code will look like this:

function widget( $args, $instance ) {
  $title = apply_filters( 'widget_title', empty($instance['title']) ? '' : $instance['title'], $instance );

This way, WPML will allow users to translate the titles of your widgets via the String Translation screen. For additional information check out the page about translating widgets.

Just like many other themes, this one uses widgets to store the footer texts.

Translating widget text using WPML’s String Translation

WPML allows users to translate the titles and content of your widgets via the String Translation screen.

10. Hiding the Language Switcher from the Settings Page

By default, WPML adds a language switcher to the WordPress admin bar. It is visible to logged-in users on both the backend and front end of your WordPress website.

The language switcher in the top admin bar

Sometimes, you may want to hide the language switcher from the settings page of your theme or plugin. This can prevent users from using the language switcher in the wrong way, like by trying to set different options for each language.

You can do this by adding the code below to your functions.php file. Just make sure to adapt it to your own needs.

Hide the language switcher from the settings page
//Make sure to rename the function before adding to your plugin
add_filter( 'wpml_show_admin_language_switcher', 'compsupp_disable_wpml_admin_lang_switcher' );

function compsupp_disable_wpml_admin_lang_switcher( $state ) {
	global $pagenow;

	// Add the admin pages that we need to hide the language switcher
	$admin_pages_to_hide_ls = array(
		'admin-page-slug', 'another-admin-page-slug', 'one-more-admin-page-slug'

	// We can also have a filter here in case we need to add/remove pages later
	$admin_pages_to_hide_ls = apply_filters( 'compsupp_filter_disable_wpml_lang_switcher_in_admin', $admin_pages_to_hide_ls);
	if (
		$pagenow == 'admin.php'
		&& isset( $_GET['page'] )
		&& in_array( $_GET['page'], $admin_pages_to_hide_ls)
	) {
		$state = false;
	return $state;

11. Creating a Language Configuration File for Your Theme

When you are done and your theme is fully WPML-compatible, you probably want to make it to be as easy as possible for others to run multilingual sites with the theme.

Create a language configuration file for your theme and save it in the theme’s root directory. The file tells WPML which custom post types, taxonomy, fields and options are translatable.

This tiny XML file will save hours for your clients, allowing them to run multilingual sites without effort. Your clients will get everything working, without the need to configure what to translate. This will also help you save on support work.

12. GetText Support for Hard-Coded Strings

Although this is not strictly related to WPML, you should remember to wrap all the strings in your theme in GetText calls. This means that hard-coded texts will appear in the correct language on the site. You should do it for both, the theme (or plugin) texts that appear in the WordPress admin area, as well as the texts displayed on the front-end.

All WordPress themes and plugins, whether they are multilingual-ready or not, should use GetText to translate hard-coded strings. The WordPress default themes use GetText very accurately and are a great reference if you are just getting started with it.

Wrapping texts in GetText calls is a big subject by itself. If you are not familiar with it or need help debugging localization for your code, have a look at these:

WPML integrates fully with GetText. Once you have wrapped hard-coded strings in GetText calls, you will be able to translate them directly from the WordPress admin using WPML’s String Translation screen. WPML can also export and import .po files for you, letting you translate your theme’s strings all from within WordPress.

13. WooCommerce Compatibility

Themes that include a WooCommerce section may need to follow a few other suggestions. Mainly, you should use get_options to get the IDs of WooCommerce pages. Have a look at our guide on making WooCommerce themes multilingual and multi-currency-ready.

14. Making Custom Elementor Widgets and Other Page Builder Widgets Translation-Ready

To allow users of your theme or plugin to translate your custom widgets, you first need to make them translatable.

To learn how, read our comprehensive guide on registering custom widgets for Elementor and other page builders for translation.

To make it easier for you to follow, the guide provides both written and video tutorials, using both basic and advanced widgets from Elementor as examples.

14. Tips and Debugging

If you are already familiar with WPML basics and are working on compatibility with your theme or plugin, have a look at the debugging theme compatibility guide. You will find tips and ideas on how to make your theme compatible with WPML.

If you need our help, just get in touch. Visit our technical support forum, explain what’s wrong and we’ll help you.