Main menu

Translation file loading

How WordPress and Loco Translate load translation files

This page provides some general advice about loading translations, whether automatically or not, and whether Loco Translate is enabled or not. It also covers various common problems.

Locations for translation files

Broadly there are three locations where translation files will exist on your server's file system. The terminology we use is as follows.

  • System
    This is what we call the installed languages directory (WP_LANG_DIR, usually at wp-content/languages). It's where translation files are managed by WordPress. When files magically appear here, they've probably been downloaded from GlotPress by automatic updates. Our plugin doesn't automatically install files and we don't maintain any translations you'll find on your system.

  • Author
    Translation files held inside a theme or plugin have been provided by the developer. We call these "author" files. For these to work, the author must call load_theme_textdomain or load_plugin_textdomain before the translations are used plus there must be no equivalent system translations installed.

  • Custom
    Loco Translate provides a "safe" location for your own custom translation files. Loading these files is our plugin's only function outside of its admin screens. It's also the function most likely to fail due to external factors.

Tip: Avoid editing files in the author and system locations. See FAQ: Why have my translation files been reverted?.

Default WordPress behaviour

Described here is the default behaviour of WordPress with our plugin disabled. If you have any problems with Loco Translate, your first course of action should always be to check this works without it.

WordPress assumes that files will be located in the system location, as a matter of priority, but it allows a fallback path to be set using load_theme_textdomain or load_plugin_textdomain.

Important: If a translation file is installed in the system location, the author provided file may not be used. See FAQ.

Loco Translate behaviour

Our plugin listens for translation files being loaded and tries to merge your custom translations with whichever file WordPress had originally selected (system or author).

If a custom file exists, the merged result will be one of "custom", "custom+system" or "custom+author". When there's no custom file, Loco Translate will do nothing and the default WordPress logic will apply.

There are many known situations where our custom file loader can't do its job. A common reason is because it's not running at the critical moment it's needed. See FAQ: Why don't translations load from the custom folder?

Timing is everything

We can't control the order in which parts of your site perform certain actions, and this is the crux of most mysterious "not working" problems. The ideal scenario is that the following events occur in order, as follows:

  1. Themes and plugins register their own file locations (if needed)
  2. Loco Translate is allowed to start (its plugin file is executed)
  3. The first translation is requested by a translation function
  4. Translation files are loaded into memory. Hooray.

Any change to this order can cause something to go wrong, and can be difficult to debug. The order is controlled by the firing of specific WordPress hooks, so plugin and theme developers have a responsibility to think about what hooks they're using. Here's some general advice, which may also help diagnose problems:

How early can you request translations?

WordPress advises not to invoke translation before the init hook has fired, but will only warn you if it's before the (earlier) after_setup_theme hook. This means calling any translation function, as they all trigger automatic file loading.

It should be noted that WordPress itself may request translations for the active theme before any translations have been requested explicitly by the theme. It does this on the init hook.

Do developers need to load their own text domain?

WordPress loads translation files automatically from the expected locations (as needed), and Loco Translate's custom file loader will be listening as long as it's been allowed to start up in time.

However, if there are "author" translations in a subfolder of a theme or plugin, the developer does need to call load_theme_textdomain (or load_plugin_textdomain) to register their fallback path. Commercial developers shipping their own translations will likely have done this, but it must be done early enough.

When should developers call load_theme_textdomain or load_plugin_textdomain?

If there are "author" translations, they must be registered before any attempt at automatic loading. That means beating other hook listeners to the chase (including WordPress itself).

Because these functions don't actually load anything, we recommend you call them as early as possible. Since WordPress 6.7 it does no harm to call load_theme_textdomain from your functions.php file (or load_plugin_textdomain from a plugin's bootstrap file) as soon as it's included. You won't receive a warning for this, and no files will be loaded yet.

Should developers call load_textdomain?

We've seen lots of plugins and theme's make direct calls to load_textdomain. Often the developer is trying to avoid WordPress de-prioritizing their own translations, but we don't recommend being too clever about it. Implementing custom file loading logic can easily have side effects and make it very hard to debug localisation problems.

In summary: Register custom paths early, but use translations late. If there are no author-provided translations, leave WordPress to load translations automatically.

See also

Last updated by