PTC

How to Import Theme and Plugin Translations into WordPress.org

Two paths put translated .po and .mo files in front of WordPress.org users. Apply for CLPTE access (4-6 days) or bundle .mo files with your release (next-day). Both work. The trade-off is canonical distribution versus speed. This guide covers when to use each path and the step-by-step for both.

You translated your plugin or theme with PTC (Private Translation Cloud) and have the .po and .mo files. Users who install your plugin from WordPress.org do not see those translations by default. WordPress.org Language Packs and your bundled files are two separate distribution channels. Pick one based on your release cadence and audience.

Path 1: Publish translations through WordPress.org Language Packs (CLPTE)

Total time: 4-6 days.

Step 1: Create a CLPTE account

The CLPTE (Cross-Locale Project Translation Editor) role lets you submit translations on behalf of your theme or plugin across every target language from one account. A regular Translation Editor account is per-language; CLPTE is not.

If you already have an account on WordPress.org, you may hit an issue where your new CLPTE account is disabled. WordPress does not allow multiple accounts. To resolve, email forum-password-resets@wordpress.org and explain that you are trying to create a CLPTE account. Sharing the relevant Polyglots documentation with the moderator and pinging the Polyglots team in Slack both help.

Estimated time: ~3-5 days (includes waiting time if your new account is disabled).

Step 2: Request CLPTE access on the Polyglots blog

With your account enabled, post a request on the WordPress.org Polyglots blog. Follow their template:

PTE/CLPTE Request

Plugin URL: https://wordpress.org/plugins/my-plugin/
Authors / Editors: @your-wp-username
Type of request: CLPTE

You get a notification when your request is approved.

Estimated time: ~1 day (Polyglots Global Team reviews requests in batches).

Step 3: Import the translated .po files

  1. Log in to https://translate.wordpress.org/ using your CLPTE account.
  2. Go to your plugin or theme's translation project page (for example, translate.wordpress.org/projects/wp-plugins/{your-plugin-slug}/).
  3. Open the local project for each language you have translated.
  4. Scroll down and click Import Translations.
  5. Upload your .po (or .mo) file.
  6. Mark the imported strings as “current” in the translation editor. Approved strings join the next Language Pack generation (typically daily).
  7. Repeat for every target language. Each locale has its own translation page.

Estimated time: ~10-30 minutes per language.

After a 24-48 hour Language Pack window, sites running your plugin start receiving the new translations through WordPress's automatic Language Pack updates. Users see no upgrade prompt. The translations just appear.

What CLPTE will and will not do for you

  • You cannot replace existing community translations. Only untranslated strings are imported. Updating an existing community translation requires the standard process and waiting for the locale team's review.
  • Updates require manual uploads for every release. Each new release means a new round of uploads.
  • Account creation and approval typically take 4-6 days in total.

Path 2: Bundle the .mo files inside your plugin or theme

If you need translations live faster than CLPTE allows, or if you would rather not depend on WordPress.org's distribution pipeline, bundle the .mo files directly in your plugin or theme release. Total time: 15-30 minutes.

Step 1: Add the .mo files to the /languages/ directory

Place your compiled .mo files inside your plugin or theme's /languages/ directory so WordPress finds them when loading your text domain:

my-plugin/
├─ my-plugin.php
├─ readme.txt
├─ languages/
│  ├─ my-plugin-es_ES.mo
│  ├─ my-plugin-es_ES.po
│  ├─ my-plugin-fr_FR.mo
│  ├─ my-plugin-fr_FR.po
│  ├─ my-plugin-de_DE.mo
│  └─ my-plugin-de_DE.po

Use the same text domain in your translation file names and your load_plugin_textdomain() or load_theme_textdomain() calls.

Step 2: Prefer your bundled files over community translations

By default, WordPress prioritizes community translations from WordPress.org over bundled ones. To make sure your plugin or theme uses the bundled .mo files instead, add the load_textdomain_mofile filter.

For plugins, add to your main plugin file (e.g., my-plugin.php):

function my_plugin_load_embedded_translation_file( $mofile, $domain ) {
    if ( 'my-domain' === $domain && false !== strpos( $mofile, WP_LANG_DIR . '/plugins/' ) ) {
        $locale = apply_filters( 'plugin_locale', determine_locale(), $domain );
        $local_mofile = WP_PLUGIN_DIR . '/' . dirname( plugin_basename( __FILE__ ) ) .
                        '/languages/' . $domain . '-' . $locale . '.mo';

        if ( file_exists( $local_mofile ) ) {
            return $local_mofile;
        }
    }
    return $mofile;
}
add_filter( 'load_textdomain_mofile', 'my_plugin_load_embedded_translation_file', 10, 2 );

For themes, add to your theme's functions.php:

function my_theme_load_embedded_translation_file( $mofile, $domain ) {
    if ( 'my-domain' === $domain && false !== strpos( $mofile, WP_LANG_DIR . '/themes/' ) ) {
        $locale = apply_filters( 'theme_locale', determine_locale(), $domain );
        $local_mofile = get_template_directory() . '/languages/' . $locale . '.mo';

        if ( file_exists( $local_mofile ) ) {
            return $local_mofile;
        }
    }
    return $mofile;
}
add_filter( 'load_textdomain_mofile', 'my_theme_load_embedded_translation_file', 10, 2 );

Also confirm your plugin or theme loads the text domain on the right hook:

add_action( 'init', function() {
    load_plugin_textdomain(
        'my-plugin',
        false,
        dirname( plugin_basename( __FILE__ ) ) . '/languages'
    );
} );

Step 3: Verify the bundled translations load on a test site

Install your plugin or theme on a test site and switch WordPress to one of the languages you have provided:

  1. Go to Settings > General > Site Language and select a language whose .mo file is in your /languages/ folder.
  2. Load a page or screen that contains strings you know are translated.
  3. Confirm the strings appear in the correct language and match the translations you added.

If you still see old community translations, review the snippet in Step 2. It needs to correctly point WordPress to your bundled .mo files.

Commit the .mo files, tag a release, and push to wordpress.org via SVN as you normally do.

The trade-off between speed and canonical distribution

  • Pro: instant. New translations are live the moment users update your plugin (or install it for the first time). No multi-day wait for CLPTE. No Polyglots-team approval cycle.
  • Pro: you control the workflow. Translation cadence matches your release cadence exactly.
  • Pro: no plugin-badge dependency. Translations work whether or not your plugin has CLPTE permissions.
  • Con: plugin file size grows. Each .mo is small (5-50KB typically), but 20 languages add ~500KB to the download.
  • Con: no auto-update of translations between plugin releases. With CLPTE, translations updated on wordpress.org propagate to users within 48 hours, even if you do not ship a new release. With bundling, translations only update when you ship a new release.
  • Con: no “translated” badge. WordPress.org displays a translation-completion badge on plugin listings based on Language Pack coverage, not bundled .mo files. Bundling alone does not earn the badge.

Which path matches your release cadence?

Situation Recommendation
Long-term canonical distribution; you want the translation badge CLPTE - go through the Polyglots application
You ship plugin updates monthly or more often, and translation cadence can match Bundle MO files
You need translations live this week and cannot wait for CLPTE Bundle MO files now, apply for CLPTE in parallel
You want both Use both - they are not mutually exclusive

The dual approach is common: bundle MO files for immediate availability, and submit to CLPTE for canonical distribution. Users get the bundled translations on update; the Language Pack overlay refreshes them between releases.

Translate your next plugin release with PTC

Start your free 30-day trial - 20,000 words on us, no credit card. Generate your .pot file, upload it to PTC, get translated .po and .mo files in minutes, ready for CLPTE or bundling.

Related: