How to translate PO and POT files

Kinga Pomykała
Kinga Pomykała
Last updated: September 10, 20256 min read
How to translate PO and POT files

PO and POT files are at the heart of gettext-based localization workflows, powering translations for frameworks like Django, WordPress, GNU projects, and many desktop or CLI apps. They've been around for decades and remain a standard in open-source and enterprise software. But how do you actually translate them?

In this guide, you'll learn how to translate PO and POT files effectively, avoid common issues, and adopt tools that make the workflow faster and safer.

What are PO and POT files?

PO (Portable Object) files store translations for a given language.
POT (Portable Object Template) files act as the source template, they contain original strings (msgid) but no translations yet.

Together, they form the gettext ecosystem for handling i18n strings.

Here's a basic example:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025 Pillow Hotel
# This file is distributed under the same license as the Pillow Hotel project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Pillow Hotel 1.0\n"
"Language: es\n"
"Content-Type: text/plain; charset=UTF-8\n"

#: templates/index.html:10
msgid "Welcome to Pillow Hotel"
msgstr "Bienvenido al Hotel Almohada"

#: templates/index.html:15
msgid "Book Now"
msgstr "Reservar ahora"

PO/POT files characteristics

Here are some key characteristics of PO/POT files:

  • File extensions: .po (translations), .pot (template).
  • Structure:
    • 'msgid' for source strings.
    • 'msgstr' for translated strings.
  • Headers store metadata (project, language, encoding, plural forms).
  • Comments:
    • Default comments (#).
    • Translator comments (#.).
    • References (#: file:line).
    • Flags (#, fuzzy).
  • Plural forms handled explicitly with indexed msgstr[n].
  • Standardized format widely supported across frameworks and tools.

PO/POT in i18n frameworks

PO/POT files are used by many ecosystems:

  • Django: uses PO files for translations, with built-in support for extracting and compiling them.
  • WordPress: relies on .po/.mo files in languages directories for themes and plugins.
  • GNU/Linux apps: gettext standard across CLI and desktop tools
  • Flask, Pyramid, PHP gettext: rely on PO files for translations
  • C, C++ projects: GNU gettext-native

Common challenges in translating PO files

Even though PO files are straightforward, translators often face challenges:

  • Fuzzy translations: Marked as uncertain, may slip into production unnoticed.
  • Plural forms: Different languages have 2–6 plural categories; mismatched rules break logic.
  • Encoding issues: UTF-8 vs. ISO-8859-1 can cause corrupted characters.
  • Context loss: Same msgid in different places may need different translations.
  • Comments ignored: Developers forget to add #. translator notes.
  • Sync issues: POT updated, but PO not regenerated → missing translations.
  • Merge conflicts: Multiple translators editing the same .po file.

Here's a broken example:

#: booking.html:12
msgid "Room"
msgstr "Habitación"

#: stats.html:45
msgid "Room"
msgstr "Sala"      # ❌ Inconsistent translation, context missing

msgid "You have %d rooms"
msgid_plural "You have %d rooms"
msgstr[0] "Tienes %d habitación"   # ❌ Wrong plural form
msgstr[1] ""                        # ❌ Empty translation

How to translate PO files

There are several ways to translate PO files, depending on the project size, team skills, and budget.

Manual translation

Small projects may translate PO files manually with a text editor.

  1. Duplicate the .pot into .po for a target language.
  2. Open the .po file in a text editor.
  3. Fill in each msgstr with the translation.
  4. Keep plural rules consistent with the language header.
  5. Compile .po into .mo using msgfmt before deploying.
Translating PO file manually
Translating PO file manually

You can translate .po files either in a text editor or in a gettext-aware editor that validates syntax and plural rules. This gives you full control but also requires caution to avoid mistakes.

Pros: no extra tools, maximum control.

Cons: error-prone, slow, poor collaboration.

Modern localization platforms like SimpleLocalize provide a user-friendly interface for translating PO files.

Here are the steps:

  1. Import .po or .pot files into the platform.
  2. Pre-translate new strongs using auto-translation.
  3. Collaborate with translators in a shared UI.
  4. QA check: placeholders, length, plural rules, fuzzy entries.
  5. Export clean .po files back into your repo.
  6. Automate sync in CI for continuous updates.
Translating PO file in SimpleLocalize

Pros: scalable, context-rich, automated sync.

Cons: requires adopting a new tool.

Learn more about translating PO files with SimpleLocalize.

Best practices for translating PO files

When working with PO/POT translation files, follow these best practices:

  • Keep POT up to date: Run xgettext whenever source changes.
  • Sync PO files regularly with msgmerge or automation.
  • Freeze source strings before translation to avoid churn.
  • Add translator notes (#.) for ambiguous terms.
  • Use placeholders consistently: %s, %d, or {name} should be documented.
  • Handle plurals correctly: Define plural rules in headers, provide all forms.
  • Validate before shipping: Run msgfmt --check to catch errors.
  • Avoid context collisions: Use pgettext for identical strings with different meanings.
  • Review fuzzy entries: Ensure they are accurate before finalizing.
  • Backup PO files: Use version control to track changes and revert if needed.

Automate PO translation with SimpleLocalize

You can turn gettext workflows into a smooth CI/CD step with SimpleLocalize:

  1. Connect your repository with GitHub App, GitLab, Bitbucket, or upload files directly.
  2. Import and scan all strings, with full msgid/msgstr structure.
  3. Pre-translate automatically. Run auto-translation for new or changed strings to create a high-quality draft instantly.
  4. Review with context. Attach screenshots, descriptions, comments.
  5. Keep translations in sync. Detect new msgids and auto-translate using an automation.
  6. Export production-ready PO files with a single click, via CI or API.
  7. Make it continuous. Wire SimpleLocalize into CI so every push:
    • imports updated PO/POT files,
    • triggers pre-translation,
    • and exports ready-to-deploy files.

Check more examples of AI-powered localization workflows.

FAQ

What is the difference between PO and POT files?

POT files are templates containing all source strings (msgid) but no translations. PO files are language-specific, storing the translated strings (msgstr). Think of POT as the blueprint and PO as the finished translation.

What is the difference between PO and MO files?

PO files are human-readable text files used for translations. MO (Machine Object) files are the compiled binary versions of PO files that gettext libraries use at runtime for faster access.

How do I create a POT file?

You can create a POT file using the xgettext command-line tool. For example:

xgettext -o messages.pot source_file1.py source_file2.py

How do I update a PO file when the source text changes?

Use the msgmerge tool to merge changes from the updated POT file into your existing PO files:

msgmerge -U translations.po messages.pot

Or use a localization platform like SimpleLocalize to automate this process.

How do I handle plural forms in PO files?

Define the plural rules in the PO file header. For example, for English:

"Plural-Forms: nplurals=2; plural=(n != 1);\n"

Then provide translations for each plural form:

msgid "You have %d message"
msgid_plural "You have %d messages"
msgstr[0] "Tienes %d mensaje"
msgstr[1] "Tienes %d mensajes"

What is a “fuzzy” translation in a PO file?

Fuzzy translations are marked as uncertain (#, fuzzy) when gettext cannot confirm accuracy. Review and correct these before deploying.

How often should I update PO files?

Update PO files whenever the source strings change. Regularly sync them with the latest POT file to ensure all translations are current.

Are there tools that help automate PO translations?

Yes, localization platforms like SimpleLocalize, Lokalise, or Crowdin offer collaborative translation, QA checks, auto-translation, and CI/CD integration.

Conclusion

PO and POT files are a cornerstone of gettext localization, powerful but tricky when managed manually. By combining good practices (plural rules, context, regular sync) with automation and collaboration in a platform like SimpleLocalize, you can eliminate fuzzy errors, merge conflicts, and tedious manual edits.

Upload your PO files, auto-translate them, invite reviewers, and export production-ready translations in minutes. Ready to streamline your gettext workflow? Import your PO files to SimpleLocalize and ship multilingual software with confidence.

Kinga Pomykała
Kinga Pomykała
Content creator of SimpleLocalize
Ready to say
|

Greet your customers
in their native language

Start for free
5-minute setupNo credit card required