How to internationalise or i18n a WordPress theme or plugin

Internationalisation, or i18n, is the process of making a WordPress theme or plugin translation ready. Localisation refers to the subsequent process of translating the text strings.

WordPress is used by millions of people so must provide support for a large number of languages. This tutorial aims to discuss how to internationalise your WordPress theme or plugin.

The most basic internationalisation function is __(). It will get a translated version of the string passed as the first argument.

$translated_text = __( 'Continue', 'text-domain' );

Escaping output

The _e() function will output a translated version of the string passed as the first argument. However, all output must be escaped so esc_html_e() and esc_attr_e() are preferred.

You use esc_html_e() to display translated text that has been escaped for safe use in HTML.

esc_html_e( 'This could be the page heading', 'text-domain' );

You use esc_attr_e() to display translated text that has been escaped for safe use in an attribute.

esc_attr_e( 'This could be alt text', 'text-domain' );

Variable data

Text can be a lot more complex than the simple strings we’ve been working with so far. If a string has a variable in it, you’ll need to use printf() and sprintf().

$translated_text = sprintf(
    __( 'My name is %s', 'text-domain' ),

If your text string has more than 1 variable in it, argument numbering is recommended.

$translated_text = sprintf(
    __( 'My name is %1$s and I live in %2$s', 'text-domain' ),


In English, the word “Comment” can be used as both a verb and a noun. In other languages the verb and noun might need to be translated separately. _x() accepts a context as the 2nd argument.

$translated_text = _x( 'Comment', 'noun', 'text-domain' );
$translated_text = _x( 'Comment', 'verb', 'text-domain' );

Plural and singular forms

At times you’ll need to handle both the plural and singular form of a string. _n() accepts the singular form of the string, the plural form, a count and a text domain and will return the translated text in the appropriate form.

$translated_text = sprintf(
        '%s comment',
        '%s comments',
    number_format_i18n( get_comments_number() )

In practice you may want to set the plural and singular strings before the number is known and perform the translation at a later date. WordPress refers to this as “pluralisation done later” and provides 3 useful functions to help us get this done.

  • _n_noop()
  • _nx_noop()
  • translate_nooped_plural()

_n_noop() is used to register the plural and singular strings but note that it doesn’t translate them.

$translation_information = _n_noop(
    '%s comment',
    '%s comments'

translate_nooped_plural() is passed the array returned by _n_noop() and returns the translated string.

$translated_text = sprintf(
    number_format_i18n( get_comments_number() )


You can provide translators with more information by adding a comment immediately before the function call. The comment must begin with “translators:”.

/* translators: This is a comment */
$translated_text = __( 'Text to be translated', 'text-domain' );

Text domain

Note that your theme or plugin must have a text domain and you must use it in every function call.

$translated_text = __( 'I love tea', 'text-domain' ); // Good
$translated_text = __( 'I love tea' ); // Bad

Posted by on .


<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>