Skip to content

GNU Gettext (.po) Translation

Lingo.dev seamlessly handles GNU Gettext (.po) files, making it perfect for applications using gettext-based internationalization. This includes applications written in C, C++, PHP, Python, Java and others.

Setting Up

First, create an i18n.json config file in your project root:

json
{
  "version": 1,
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de"]
  },
  "buckets": {
    "po": {
      "include": ["locales/[locale]/LC_MESSAGES/messages.po"]
    }
  }
}

This config tells Lingo.dev:

  1. Your source language is English;
  2. You want to translate to Spanish, French, and German;
  3. Your .po files follow the standard gettext directory structure.

Available Languages

Lingo.dev supports a wide range of languages. To see what's available:

bash
npx lingo.dev@latest show locale sources  # List available source languages
npx lingo.dev@latest show locale targets  # List available target languages

Use these to pick the right locale codes for your project.

Translating

With your config set, run:

bash
npx lingo.dev@latest i18n

Lingo.dev will:

  1. Read your source .po files;
  2. Identify new or changed strings;
  3. Translate them to your target languages;
  4. Update or create the target .po files in their respective directories.

How It Works

Lingo.dev's approach is effective because:

  1. It follows the standard gettext directory structure, integrating seamlessly with existing tooling;
  2. It understands context, providing more accurate translations than traditional word-for-word methods;
  3. It's incremental, only translating what's new or changed, saving time and processing power.

Pro Tips

  1. Message Context: Lingo.dev preserves gettext message contexts, ensuring accurate translations:

    po
    msgctxt "Menu"
    msgid "Open"
    msgstr "Abrir"
    
    msgctxt "File"
    msgid "Open"
    msgstr "Abrir archivo"
  2. Pluralization: Lingo.dev handles gettext's plural forms correctly:

    po
    msgid "Found %d item"
    msgid_plural "Found %d items"
    msgstr[0] "Encontrado %d elemento"
    msgstr[1] "Encontrados %d elementos"
  3. File Exclusions: You can exclude specific files or directories:

    json
    {
      "buckets": {
        "po": {
          "include": ["locales/*/LC_MESSAGES/*.po"],
          "exclude": ["locales/*/LC_MESSAGES/admin.po"]
        }
      }
    }
  4. Multiple File Types: You can configure multiple file types:

    json
    {
      "buckets": {
        "po": {
          "include": ["locales/*/LC_MESSAGES/*.po"]
        },
        "markdown": {
          "include": ["docs/[locale]/*.md"]
        }
      }
    }

By leveraging these features, you can maintain a robust, scalable i18n setup using GNU Gettext. Lingo.dev's understanding of .po file formats and gettext conventions makes it an excellent choice for managing translations in gettext-based projects.