Supported File Types (Strings)

.PO - gettext files (Strings)

Content is machine translated from English by Phrase Language AI.

File Extensions


API Extension






Plural forms support


Description support


.PO (Portable Object) is the standard file format for localization with GNU gettext, an open-source GNU library designed to simplify the localization process. With GNU gettext, localizable strings are extracted from source code into a PO file for translation. A .PO file is a series of key-value pairs. The key msgid is where the source string is placed while the value msgstr is where the translation goes.

gettext extracts strings from source code into a .POT (portable object template). Based on defined locales, gettext then converts the .POT file into a locale-specific .PO files for upload to a CAT tool for translation. After translation, gettext converts the translated .PO files into .MO files (machine object files) eventually used for localization.

.PO files are identical to .POT files excepting .POT files are generally used by gettext to generate locale-specific .PO files. Translating a .POT file directly and renaming it according to the later intended locale does not generate problems. Phrase supports the translation of:

  • .PO files

    • Ensure the Msgid as default translation option is enabled.

      If not enabled, the key name (msgid) will be imported but the source (msgstr) will be empty.

  • Bilingual .PO files

    Select Import bilingual .po files when uploading a file via Strings user interface to enable relevant import options.

    • msgid is the default source translation and key name

    • msgstr is the default target translation

    • msgctxt is added to the msgid with ||

  • .POT files

  • Machine-readable .MO files

Code Sample

msgid ""
msgstr ""
"Language: English\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: PhraseApp (\n"

msgid "boolean_key"
msgstr "--- true\n"

msgid "empty_string_translation"
msgstr ""

# This is the amazing description for this key!
msgid "key_with_description"
msgstr "Check it out! This key has a description! (At least in some formats)"

msgid "key_with_line-break"
msgstr "This translations contains\na line-break."

msgid "nested.deeply.key"
msgstr "Wow, this key is nested even deeper."

msgid "nested.key"
msgstr "This key is nested inside a namespace."

msgid "null_translation"
msgstr ""

msgid "pluralized_key"
msgid_plural ""
msgstr[0] "Only one pluralization found."
msgstr[1] "Wow, you have %s pluralizations!"

msgid "sample_collection"
msgstr "---\n- first item\n- second item\n- third item\n"

msgid "simple_key"
msgstr "simple key, simple message, so simple.2"

#, fuzzy
msgid "unverified_key"
msgstr "I need verification, please verify me! (In some formats we also export this status)"

Typical gettext entry:

# description (Optional)
msgid "key-name"
msgstr "My Translation"

gettext Header

The header of a gettext file may contain a locale name and data for plural forms that is extracted during import:

msgid ""
msgstr ""
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: PhraseApp (\n"


Comments in a gettext file are added as key descriptions during import:

# This is my description
msgid "app_title"
msgstr "My Software Project"


gettext uses the msgctxt notation to distinguish different contexts for the same msgid. Every key name must be unique so msgctxt is added as the first part of the key name, separated by two pipe symbols ||:

msgctxt "menu"
msgid "Open"
msgstr "I'am a translation"

msgctxt "forum"
msgid "Open"
msgstr "I'am some other translation"

To add the msgctxt to a new key, prepend it to the key name:


Resulting gettext output:

msgctxt "my_context"
msgid "my_key_name"

Plural forms

gettext supports plural forms for a translation:

msgid "new_messages"
msgid_plural ""
msgstr[0] "You have a new message"
msgstr[1] "You have %{count} new messages"


The fuzzy keyword is used for translator verification. Fuzzy automatically invokes the unverification process within the app.

#, fuzzy
msgid "app_title"
msgstr "My Software Project"
Was this article helpful?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.