Loco Translate Shows 1,000+ Translated Strings but the Plugin Admin Interface Stays English

A frustrating WordPress translation problem can look like this:

Loco Translate
→ Plugin
→ Language
→ 1,000+ strings translated
→ Saved successfully

But...

Plugin admin interface
→ Still completely English

If none of the translated strings appear inside the plugin’s wp-admin interface, translating more strings is unlikely to solve the problem.

There are several possible causes, but with modern WordPress plugins the most important question is:

Is the plugin’s admin interface generated by PHP, or is it a JavaScript application?

Loco Translate can successfully display and save translatable strings without guaranteeing that the plugin actually loads those translations in the part of its interface where they are used.

For a JavaScript-based admin panel, .po and .mo files alone are generally not enough. The plugin also needs to integrate its scripts with WordPress’s JavaScript internationalization system. WordPress documents wp_set_script_translations() as the mechanism for attaching translated strings to a registered script.

That is one of the first things I would investigate when none of hundreds or thousands of translated admin strings appear.

First Check: Your WordPress User Language

Before debugging the plugin, check the simplest possibility.

Go to:

Users
→ Profile
→ Language

and select the language you translated.

Then reload the plugin page.

This matters because WordPress admin screens normally use the current user’s locale, not necessarily the site’s public language.

WordPress’s current determine_locale() implementation explicitly calls:

get_user_locale();

for wp-admin requests. If the user does not have a separate language selected, WordPress falls back to the site locale.

For example:

Settings → General → Site Language
German

but:

Users → Your Profile → Language
English (United States)

can legitimately result in:

Frontend
→ German

wp-admin
→ English

That includes correctly internationalized plugin interfaces.

Quick Test

Temporarily set both:

Site Language
German

and:

Your User Language
German

Then:

Log out
→ log back in
→ open plugin admin page

If translations suddenly appear, there is no Loco Translate problem.

The plugin was simply being loaded under a different admin locale.

If Zero Translations Appear, Test One Obvious PHP String

Don’t begin by troubleshooting all 1,000 strings.

Choose something simple such as:

Settings
Save
General
Dashboard
Enable

Translate it into something intentionally obvious.

For example:

Settings
→ TEST-TRANSLATION-123

Save the Loco file and reload the plugin screen.

If:

TEST-TRANSLATION-123

never appears anywhere, determine whether that particular string comes from:

PHP

or:

JavaScript

because those translation paths are different.

Modern Plugin Admin Interfaces Are Often JavaScript Applications

Older WordPress settings pages commonly generated markup directly in PHP:

<h2>
    <?php esc_html_e( 'Settings', 'my-plugin' ); ?>
</h2>

That works through WordPress’s normal gettext system:

PHP
↓
Text domain
↓
.mo / .l10n.php translations
↓
Translated HTML

Loco Translate is very good at this traditional workflow.

Modern plugin dashboards, however, are often built with:

React
Vue
Angular
compiled JavaScript bundles
WordPress components

The PHP page may contain little more than:

<div id="plugin-app"></div>

and JavaScript generates the entire interface afterward.

In that situation the path becomes:

JavaScript bundle
↓
wp.i18n
↓
script-specific translation data
↓
translated interface

WordPress says JavaScript strings should use functions such as:

__(
    'Settings',
    'my-plugin'
);

and the associated script must have its translations registered with:

wp_set_script_translations(
    'my-plugin-admin',
    'my-plugin'
);

If the plugin developer omitted that second part, Loco Translate can contain a perfectly valid translation while the browser never receives it.

Why Loco Can Show a String That the Plugin Still Doesn’t Translate

This is a common point of confusion.

Suppose Loco displays:

Original:
Dashboard

Translation:
Tableau de bord

Status:
Translated

That only proves that the translation exists in your translation project.

It does not prove this runtime code:

document.querySelector(...).textContent = 'Dashboard';

uses WordPress translation functions.

If the developer hardcoded:

const title = 'Dashboard';

then Loco cannot magically replace it.

Similarly, a .pot file may contain strings that no longer correspond correctly to the current source code.

Loco’s own troubleshooting documentation explicitly warns that a bundle’s template may list strings without guaranteeing that the current application actually loads them through WordPress’s translation system.

JavaScript Translations Require JSON Translation Data

For standard PHP translations you normally encounter:

.po
.mo

For WordPress JavaScript translations, you may additionally find generated:

.json

language files.

Loco Translate supports WordPress’s JSON translation format and can generate these files when saving a PO translation.

A language folder might therefore contain:

my-plugin-fr_FR.po
my-plugin-fr_FR.mo

my-plugin-fr_FR-a7d973....json
my-plugin-fr_FR-63e913....json

Those JSON files correspond to individual JavaScript files.

If the admin interface is primarily JavaScript and no appropriate JSON translations are being generated or loaded, that is a strong explanation for:

PHP strings translated
maybe

JavaScript admin UI
still English

Check Whether Loco Generated JSON Files

Open:

Loco Translate
→ Plugins
→ affected plugin
→ your language

Save the translation again.

Then inspect the translation directory.

If you selected Loco’s Custom location, it will normally be under:

/wp-content/languages/loco/plugins/

Loco recommends this location because normal plugin and WordPress language directories can be overwritten by updates.

Look for:

plugin-domain-xx_XX.po
plugin-domain-xx_XX.mo

and, if JavaScript strings are involved:

plugin-domain-xx_XX-<hash>.json

If you translated many JavaScript admin strings but Loco creates no relevant JSON files, press:

Sync

inside Loco and investigate how the plugin’s JavaScript sources are referenced.

Why JSON Generation Can Fail

Loco generates WordPress JavaScript translations using source-file references stored in the PO data.

For example:

#: assets/js/admin.js:124
msgid "Save Settings"
msgstr "..."

may generate a JSON language pack whose filename corresponds to:

assets/js/admin.js

However, imagine the plugin developer builds:

Source:
src/settings/App.jsx

into:

Production:
build/admin.8f72c1.js

If the translation metadata points to:

src/settings/App.jsx

while WordPress actually registers:

build/admin.8f72c1.js

the calculated translation filename may not match the script WordPress loads.

Loco explicitly documents this as a common JavaScript translation failure. The path referenced by the translation catalog must correspond correctly to the actual runtime JavaScript file.

This is generally something the plugin developer needs to fix.

Developer Check: Look for wp_set_script_translations()

If the plugin is open source, search its code for:

wp_set_script_translations

For example:

grep -Rni "wp_set_script_translations" \
wp-content/plugins/plugin-folder/

For a normal script-based admin application, you would expect something conceptually like:

wp_enqueue_script(
    'plugin-admin',
    plugins_url(
        'assets/admin.js',
        __FILE__
    ),
    array( 'wp-i18n' ),
    $version,
    true
);

wp_set_script_translations(
    'plugin-admin',
    'plugin-text-domain'
);

WordPress documents that wp_set_script_translations() only works for a registered script and associates that script with the correct text domain.

If the plugin contains hundreds of:

__( ...)

calls but never calls:

wp_set_script_translations()

for its admin bundle, that is a likely plugin internationalization bug.

WordPress 7 Also Supports Script Module Translations

Modern plugins may now use WordPress’s Script Modules API instead of conventional enqueued scripts.

WordPress 7.0 introduced:

wp_set_script_module_translations()

for assigning translations to registered script modules.

So a very new plugin might need something like:

wp_set_script_module_translations(
    'my-plugin-admin',
    'my-plugin',
    plugin_dir_path( __FILE__ ) . 'languages'
);

instead of the traditional script function.

If a plugin migrated its admin application to JavaScript modules but failed to migrate its localization setup, translations can disappear even though all strings remain visible inside Loco.

Check the Text Domain

Every WordPress plugin should use one consistent text domain.

For example:

__(
    'Settings',
    'example-plugin'
);

must correspond with translations built for:

example-plugin

not:

example_plugin

or:

exampleplugin

Loco’s own troubleshooting guide identifies incorrect text domains and incorrectly named translation files as a common reason translations do not load.

Check the plugin header:

/*
Plugin Name: Example Plugin
Text Domain: example-plugin
Domain Path: /languages
*/

Then search some actual strings:

grep -Rni "__(" \
wp-content/plugins/example-plugin/

You want the domain used in code to match:

Text Domain: example-plugin

consistently.

A plugin could accidentally have:

__( 'General', 'example-plugin' );
__( 'Dashboard', 'example_plugin' );
__( 'Save', 'old-plugin-name' );

Loco may extract all of them, but your translation file for one domain will not automatically translate the others.

Inspect the Browser for JavaScript Translation Data

Open the untranslated plugin admin page.

Use:

F12
→ Elements / Sources

and search for:

setLocaleData

or:

wp.i18n

A properly localized WordPress script often receives translation data before the application code executes.

You may see something conceptually similar to:

wp.i18n.setLocaleData(
    {
        "Settings": [
            "Paramètres"
        ]
    },
    "my-plugin"
);

If:

wp.i18n
✓ loaded

plugin admin bundle
✓ loaded

translation data for plugin domain
✗ missing

the browser has no translated strings to use.

That is strong evidence for the plugin developer.

Test the Translation Function From the Browser Console

If wp.i18n is available, you can run a simple diagnostic.

Suppose the English string is:

Settings

and the plugin domain is:

my-plugin

Run:

wp.i18n.__(
    'Settings',
    'my-plugin'
);

If it returns:

Settings

instead of your translation, WordPress’s JavaScript translation store does not currently have that translation available.

If it returns:

Paramètres

but the plugin interface still says:

Settings

then the plugin is probably not using wp.i18n for that UI element, or it cached/hardcoded the English string elsewhere.

That test is extremely useful.

Check the Translation File Location

Loco offers several locations.

You may see:

Author
System
Custom

For your own translations, Loco recommends:

Custom

which normally means:

wp-content/languages/loco/plugins/

This directory is protected from normal plugin and language-pack updates.

Avoid relying on:

wp-content/plugins/plugin-name/languages/

because a plugin update can overwrite that directory.

Also avoid keeping irreplaceable custom translations directly under WordPress-managed language locations unless you understand the update behavior.

WordPress 6.7+ Can Expose an “Early Translation Loading” Bug

There is another important possibility on newer WordPress versions.

Loco documents a compatibility problem introduced around WordPress 6.7 when a plugin attempts to use its translations too early, before other plugins such as Loco have had an opportunity to hook into translation loading.

Enable WordPress debugging temporarily and check:

wp-content/debug.log

for a message resembling:

Translation loading for the "plugin-domain"
domain was triggered too early.

If you see that exact plugin text domain, the plugin’s localization code likely runs before it should.

This can particularly affect translations stored in Loco’s custom directory.

The proper fix belongs in the plugin.

Do not modify WordPress core or move every translation file around permanently just to mask an early-loading bug.

Test the Standard WordPress Language Directory

Loco recommends an excellent diagnostic.

If your Custom file currently lives at:

wp-content/languages/loco/plugins/
plugin-domain-de_DE.mo

temporarily use Loco’s Relocate function to test:

wp-content/languages/plugins/
plugin-domain-de_DE.mo

Then reload the plugin admin screen.

If:

System location
✓ works

Loco Custom location
✗ does not

that points toward a custom-file loading/timing issue.

If:

System
✗

Custom
✗

then the cause is probably:

wrong locale
wrong domain
JavaScript translations
hardcoded strings
incorrect plugin implementation

rather than Loco’s custom loader.

Do not leave your custom translation in the System location indefinitely without understanding that WordPress language updates can overwrite it.

Press Sync in Loco Translate

Plugin authors update their source code.

Your Loco translation might still be based on an older:

.pot

or:

.po

catalog.

Open:

Loco Translate
→ Plugins
→ plugin
→ language
→ Sync

Then review the result.

You might see:

145 new strings added
43 obsolete strings removed

After Sync:

translate new strings
→ Save

This can also update source references that Loco needs when generating JavaScript JSON files.

Loco’s documentation explains that Sync refreshes a translation against the current available strings/template.

Check Whether the Strings Are Actually Stored in the Database

Not everything visible in a plugin UI is a gettext translation.

Loco handles static program strings.

It does not translate normal dynamic content stored in the WordPress database.

For example, a plugin may have initially inserted:

Dashboard
Reports
Settings

into an option or custom database table during activation.

Later its UI may output:

echo $settings['menu_label'];

instead of:

esc_html_e(
    'Dashboard',
    'my-plugin'
);

In that case the English text is database data.

Changing:

.po / .mo

will not affect it.

This can also happen with:

email templates
form labels
saved default settings
page titles
custom field labels
notification text

If the string was stored as data when the plugin was installed, you may need to change it in the plugin’s own settings instead.

An Important Clue: Absolutely Nothing Translates

There is a meaningful difference between:

900 strings work
100 strings don't

and:

0 of 1,000+ strings work

If none of the translated admin strings appear, I would prioritize the causes in roughly this order:

  1. Admin user language does not match the translated locale.
  2. Plugin admin interface is JavaScript and its script translations are not loaded.
  3. Wrong plugin text domain / translation filename.
  4. Plugin forces or loads a different translation source.
  5. Translation loading occurs too early.
  6. The visible strings are hardcoded or stored in the database.

A browser cache is much less convincing when the entire translation system fails.

Don’t Spend Hours Clearing Page Cache

This is a wp-admin translation problem.

Full-page caching plugins usually do not cache logged-in WordPress admin pages in the same manner as public pages.

A browser hard refresh is sensible:

Ctrl + Shift + R

and clearing object/opcode caches after changing PHP files can sometimes help.

But repeatedly purging:

page cache
CDN cache
frontend cache

is unlikely to fix a plugin that failed to register its JavaScript translations.

Follow the translation chain instead.

Developer Fix for a JavaScript Admin App

Suppose a plugin has:

import {
    __
} from '@wordpress/i18n';

const heading = __(
    'Plugin Settings',
    'my-plugin'
);

Its PHP registration should include translation support.

Conceptually:

wp_register_script(
    'my-plugin-admin',
    plugins_url(
        'build/admin.js',
        __FILE__
    ),
    array(
        'wp-i18n',
    ),
    '1.0.0',
    true
);

wp_enqueue_script(
    'my-plugin-admin'
);

wp_set_script_translations(
    'my-plugin-admin',
    'my-plugin',
    plugin_dir_path( __FILE__ ) . 'languages'
);

WordPress explicitly requires associating the text domain with the registered script for JavaScript localization to work.

If this code is missing, that is something the plugin author should correct.

The Plugin Must Also Internationalize Every Displayed String

Adding:

wp_set_script_translations()

is not enough if the UI contains:

const saveButton = 'Save Changes';

Instead, it must contain:

const saveButton = __(
    'Save Changes',
    'my-plugin'
);

WordPress’s internationalization guidelines state that user-facing strings need to be wrapped in the appropriate i18n function.

The same applies to:

tooltips
modal titles
notifications
placeholder text
buttons
tabs
error messages

If they’re hardcoded inside a bundled JavaScript application, Loco cannot translate them at runtime.

What to Send the Plugin Developer

If all of the following are true:

Correct WordPress user language
✓

Correct locale
✓

Loco translation saved
✓

PO/MO files exist
✓

Loco Sync completed
✓

Admin remains 100% English
✗

send the plugin author a reproducible report.

Include:

WordPress version
Plugin version
Loco Translate version
Target language / locale
Plugin text domain
Location of PO/MO files
Whether JSON files were created
Whether PHP strings translate
Whether JavaScript admin strings translate

Then say something like:

Loco Translate successfully extracts and saves the admin interface strings, but none of them are loaded in the plugin UI. The admin page appears to be JavaScript-driven. Could you confirm whether the admin script is internationalized using wp.i18n and registered with wp_set_script_translations() (or the appropriate Script Modules translation API)?

That is much more useful than simply saying:

Loco Translate doesn’t work.

Loco itself recommends contacting the plugin author once the translation files are known to exist but the bundle does not load them correctly.

Recommended Troubleshooting Order

Use this sequence:

1. Set your WordPress USER language
   to the translated language.

2. Log out and back in.

3. Open Loco Translate and press Sync.

4. Save the translations again.

5. Confirm the locale is correct:
   de_DE, fr_FR, es_ES, etc.

6. Confirm the translation's text domain.

7. Confirm .po and .mo files exist.

8. If the admin is JavaScript-based,
   look for generated .json files.

9. Inspect the admin page for
   wp.i18n / setLocaleData.

10. Check debug.log for:
    "Translation loading ... triggered too early."

11. Temporarily test the standard
    wp-content/languages/plugins path.

12. If still broken, report the
    plugin's internationalization implementation.

This isolates the real failure much faster than translating another thousand strings.

Most Likely Cause in This Scenario

The strongest clue in the reported case is:

More than 1,000 strings are translated, but none appear in the plugin’s admin interface. Other plugins work normally with Loco Translate.

That makes a site-wide Loco Translate failure relatively unlikely.

The first thing I would verify is the current administrator’s User Language.

If that is correct, my next suspicion would be that this particular plugin’s admin interface is JavaScript-driven and either:

does not call wp_set_script_translations()

or:

does not generate/load correctly matched JSON
translation files

or simply contains hardcoded JavaScript UI labels.

WordPress and Loco both require cooperation from the plugin’s localization implementation for script-based interfaces.

Direct Answer

Loco Translate can successfully show:

1,000+ translated strings

while the plugin UI remains English because Loco is primarily an editor/compiler for translation files. It cannot force a plugin to use those translations.

First verify:

Users → Profile → Language

because WordPress admin screens use the current user’s locale.

If the language is correct, determine whether the plugin admin interface is generated in JavaScript.

For modern JavaScript interfaces, the plugin needs proper WordPress i18n functions plus:

wp_set_script_translations()

or, for WordPress 7 script modules:

wp_set_script_module_translations()

so the browser receives the translated strings.

If the plugin does not implement that correctly, this is a plugin internationalization issue, not something that translating more strings in Loco will solve.

About the author

Tahrim Naziat

WordPress and Server Troubleshooting Specialist

Tahrim Naziat is a senior WordPress and JavaScript developer with more than 14 years of experience specializing in WordPress troubleshooting, WooCommerce, PHP compatibility, plugin conflicts, malware cleanup, performance optimization, Nginx, Redis, and production server issues. He documents practical solutions based on real WordPress debugging, technical investigations, and client projects.

Leave a Comment