AumCreate

.pot, .po and .mo: what WordPress language files are and how to translate one

· updated October 18, 2026· screens checked September 23, 2026

A theme or plugin ships a .pot file containing every translatable string without translations. Copy it to a .po file for the target language and fill in the translations. Then compile the .po into a .mo, the format WordPress reads at runtime. A .po file alone has no effect on the site.

When a completed translation does not appear on the site, the usual causes are a missing compile step or an incorrect filename. Both are covered in the last sections of this page.

The three file types

  • .pot: the template. Every translatable string in the theme or plugin, with empty translations. The developer generates it from the source code; it is copied, not edited.
  • .po: one language. Human-readable text with each original string followed by its translation. This is the file used for translation work.
  • .mo: the compiled version of a .po. Binary and not intended to be read. This is the file WordPress loads.

Since WordPress 6.5 there is a fourth format: a .l10n.php file, which loads faster and is used when present, with .mo as the fallback. It does not need to be created manually; WordPress can generate it, which is why it may appear in the languages folder without being added.

Translating a .pot file

  1. Locate the .pot file. It is usually in the plugin or theme folder, under languages/.
  2. Copy it to a file named for the target language with the .po extension, following the naming rule in the next section.
  3. Translate the entries, either one by one in a PO editor or in bulk. Keep every placeholder exactly as it appears in the original.
  4. Compile the .po into a .mo and place both files where WordPress looks for them. If gettext is not installed, the free browser-based compiler handles the compile step.

For large files, the PO / POT translator translates the whole file in one pass and exports it in the same format. Only the strings are sent; the file itself is not uploaded.

File naming

WordPress looks for {text-domain}-{locale}.mo. If the name differs by a single character, WordPress does not load the file and falls back to English without any error or notice. This is the most common reason a completed translation has no effect.

  • The text domain belongs to the plugin or theme, for example woocommerce, twentytwentyfive or my-cool-plugin. It is declared in the plugin header and does not always match the folder name.
  • The locale is the WordPress locale, not the two-letter language code. Simplified Chinese is zh_CN, English is en_US and French is fr_FR, while Japanese is ja, Arabic is ar and Finnish is fi, with no region code.
  • If the source file already includes a locale, such as woocommerce-en_US.po, remove it before adding the new one. Otherwise the result is woocommerce-en_US-zh_CN.mo, which matches no locale.

File locations

WordPress loads translations from two locations, which differ in how updates affect them.

  • wp-content/languages/plugins/ and wp-content/languages/themes/: recommended. WordPress checks these first, and plugin or theme updates do not overwrite files here.
  • The plugin’s or theme’s own languages/ folder: also loaded, but the next update replaces the folder, including the translation.

Troubleshooting a translation that does not appear

  1. Confirm that a .mo file exists. A .po file alone has no effect.
  2. Confirm that the filename is exactly {text-domain}-{locale}.mo. Check the text domain in the plugin header and the locale against the WordPress locale list.
  3. Confirm that the site language is set to that language under Settings → General.
  4. Confirm that the file is in wp-content/languages/…. A file stored only in the plugin folder is removed when the plugin updates.
  5. If the translation still does not appear, clear any object or page cache. Translations are loaded once per request and cached.

Placeholders

Strings such as Showing %1$s of %2$s results contain placeholders that PHP fills in. If a translation drops a placeholder, reorders placeholders without the numbered form, or replaces %s with the full-width %s, the result is a runtime error on the page, not a display issue. Check placeholders before deploying the file; a compiler with placeholder checks flags these errors.

Common questions

Can the .po file be uploaded on its own?
No. WordPress reads `.mo` (and `.l10n.php` since 6.5), not `.po`. A `.po` file in the languages folder has no effect: no error is reported and the site remains in English.
Is gettext or Poedit required?
Not for the compile step. A browser-based tool can convert a .po into a .mo without any installation. [The AumCreate PO compiler](/tools/po-compiler?utm_source=guide&utm_medium=tutorial&utm_campaign=po-files) runs locally in the browser, and the file is not uploaded. A desktop PO editor is better suited to detailed line-by-line editing.
What about strings that are not in the .pot?
These strings are not marked as translatable in the source code, so no language file can translate them. This requires a change to the theme or plugin itself. Site content such as pages, products and posts is translated with a multilingual plugin rather than a .po file.
Why is the theme translated while plugins remain in English?
Each theme and plugin has its own text domain and its own language file, so translating one does not affect the others. For languages WordPress supports, many plugins receive translations automatically from translate.wordpress.org. Commercial plugins are often not covered.

Plugin used in this guide

AumLangTranslate supported Elementor, Gutenberg, and WooCommerce content, with language-specific URLs, hreflang, per-language canonical settings, and multilingual sitemap support.Plugin page →