Back to blog

A Dev's Guide to the 10 Types of Translations

2026-04-12 21 min read
A Dev's Guide to the 10 Types of Translations

You ran makemessages, opened locale/fr/LC_MESSAGES/django.po, and got hit with the usual feeling. Half the strings are tiny UI labels. A few are messy validation errors. Some have placeholders. A few are clearly marketing copy that shouldn't sound like a robot wrote them.

Then the bad options show up.

Option one is manual copy-paste into Google Translate and a long evening of fixing broken %(name)s placeholders. Option two is buying a translation platform that expects a localization manager, vendor workflows, and a budget that makes no sense for a small Django app.

Both options are bad for many teams.

The core problem is that people talk about translation like it's one thing. It isn't. In software, especially in Django, translation is a set of different strategies. Each one fits a different kind of string, a different release cadence, and a different risk level. A checkout error message, a pricing page headline, and a privacy policy shouldn't all go through the same workflow.

That matters because many Django teams already have the hard part in place. You use gettext. You have .po files. You can extract and compile messages. What usually breaks is everything after extraction. Teams translate too much at once, review too little context, or push important strings through the same pipeline as throwaway admin labels.

The useful question isn't "how do I translate my app?" It's "which types of translations belong in which part of my Django project?"

That's the lens that helps. Pick the right method for the right strings. Automate the boring parts. Keep humans where mistakes are expensive. Put the whole thing in Git so you can review changes like code instead of chasing them through a portal.

Here are the translation types that matter in a real Django workflow.

1. Machine Translation with LLMs

A common Django scenario looks like this: django-admin makemessages runs, a few hundred new strings land in a .po file, release day is close, and nobody wants to translate button labels and validation errors by hand. That is the job machine translation handles well.

For developers, the appeal is simple. LLM-based translation fits the workflow you already have. Extract strings, translate entries in the .po file, review the diff, then ship compiled locales through the same CI/CD pipeline you use for code. No spreadsheet export. No copy-paste into random tools. No side system that drifts from the repo.

Where it works

Machine translation is a practical fit for:

If you're choosing an engine, generic benchmark pages are less useful than an engine comparison built around gettext files, placeholders, and review workflow. This breakdown of GPT-4 vs Claude vs DeepL for Django translations is closer to the decision most Django teams need to make.

A diagram illustrating how a large language model performs machine translation between different languages.

What makes it work in a real project

The model matters less than the process around it.

Teams get decent results when they feed the model short, well-scoped units and enforce a few hard rules in CI. Without that, LLM output looks fine in a demo and causes cleanup work later.

A setup that holds up in production usually includes:

The trade-off is straightforward. MT is fast and cheap per string, but it is weak at product nuance, legal precision, and any text where tone carries real business weight.

Practical rule: Use MT for coverage and speed. Review the strings that can affect trust, conversion, support volume, or compliance.

For many Django teams, that is the right first layer. It gets broad language coverage into the app without turning localization into a separate department.

2. Human Translation Professional Services

A release is ready. makemessages picked up a new batch of strings, CI is green, and the product team wants to ship today. Then someone notices that the checkout disclaimer, refund policy, and paid acquisition copy were all translated with the same workflow used for button labels.

That is where professional human translation belongs in a Django project. Use it for strings where a wording mistake creates legal exposure, weakens conversion, or makes the product sound careless.

Where humans are worth the cost

Human translators earn their keep on text that carries business risk or brand weight:

This is also the part of the stack where cheap shortcuts usually create expensive cleanup. A mistranslated CTA hurts conversion. A sloppy policy translation creates support tickets, legal review, or both.

How this fits into a Django workflow

Treat human translation as a targeted review lane inside the same pipeline you already use for code.

A practical setup looks like this:

That structure keeps the work auditable. It also avoids a common failure mode: strings get edited in some vendor portal, then reappear in the repo later with no context, no reviewer, and no clear diff.

Context matters more here than in any other translation path. A translator can do good work from a .po file if the file contains useful clues. Translator comments, source references, screenshots, and field-level notes all reduce guesswork. Charge in a billing screen is not the same string as Charge in a battery status panel.

What to outsource, and what to keep in-house

Do not send the whole locale tree just because a vendor asked for "all source files." That is how teams overspend on low-value UI strings.

Send the subset that benefits from human judgment. Keep routine interface text in your normal app workflow unless there is a clear reason to escalate it. In practice, the handoff set is usually small: checkout flows, plan descriptions, legal text, onboarding copy, and anything tied to trust.

The trade-off is simple. Human translation gives better judgment and better phrasing, but it adds cost, handoff time, and review overhead. In a fast-moving Django codebase, that means the scope has to stay tight.

Use humans where mistakes are expensive. Keep the rest of the pipeline lean.

3. Hybrid Translation Approach

A Django team usually reaches hybrid after the same failure twice. Raw machine output ships too fast and misses nuance. Full human review slows releases and clogs the queue with low-risk strings. Hybrid fixes that by putting review effort where it pays off.

In practice, the flow is simple. Extract strings, prefill the untranslated entries, run validation, then send a smaller review set to a human. The unit of work stays the .po file and the diff, not a separate portal that drifts away from the repo.

For Django projects, that often looks like this:

  1. Run makemessages.
  2. Fill empty msgstr values with machine output.
  3. Check placeholders, plural forms, and syntax in CI.
  4. Route selected entries to human review.
  5. Merge reviewed .po changes and run compilemessages.

The main advantage is operational, not theoretical. Hybrid matches how software teams already ship. The machine handles scale. Humans spend time on strings that can hurt conversion, trust, or support volume if they read badly.

A good review rule matters more than the translation engine. Without one, teams end up reviewing thousands of harmless labels while missing the few strings that carry business risk. If you need a product-level distinction between translation work and broader adaptation, this guide on localization vs internationalization in software products is a useful reference.

A practical split works well:

The trade-off is straightforward. Broader human review improves phrasing, but it also adds queue time, cost, and another handoff to manage in CI/CD. In a fast Django release cycle, that overhead is only worth paying for the strings users notice or depend on.

If the review backlog keeps growing, the usual problem is scope. Cut the handoff set. Keep low-risk UI text in the automated path, and make human review a targeted step instead of the default for every locale file.

4. Localization Beyond Translation

Translation changes words. Localization changes the product.

That's an important distinction because a Django app can have perfect French strings and still feel broken in France if dates, currency, address formats, or layout assumptions stay English-first.

Some of the most useful types of translations for developers are not really about wording at all. They're about adapting the app so the translated text lands in a product that feels local.

For a closer product-level distinction, this guide on localization vs internationalization is worth keeping in mind while planning your stack.

A conceptual illustration showing two smartphones with interface differences reflecting localization for Western and Eastern markets.

What changes in a Django app

Localization usually touches:

At this point, many teams learn the hard way that translated strings are the easy part.

A practical example:

from django.utils import formats
from django.utils import timezone

def invoice_context(request, invoice):
    return {
        "issued_at": formats.date_format(timezone.localtime(invoice.created_at), "DATETIME_FORMAT"),
        "total": formats.number_format(invoice.total, use_l10n=True),
    }

If you don't test locale formatting in real templates and forms, you'll miss problems until users report them.

What works and what doesn't

What works is layering localization after basic translation is stable. Ship the strings first. Then audit user flows by locale.

What doesn't work is assuming gettext solves product adaptation by itself. It doesn't.

The string is only one part of the user experience. Locale bugs usually show up in forms, payments, dates, and layouts.

Keep translation and localization connected, but don't pretend they're the same task.

5. Community-Driven Translation

If you maintain an open-source project or a product with an active user base, community translation can work surprisingly well. It can also collapse into chaos if you don't set rules.

The upside is obvious. Passionate users know the product, care about the language, and often catch awkward wording that a generic translator won't. The downside is consistency. Without structure, every volunteer translates the same term differently.

Where this fits

Community-driven translation is common in docs-heavy or open-source ecosystems. It works best when the community already contributes in other ways, such as docs, bug reports, or support.

A good setup has three ingredients:

You can also seed community efforts with machine translation, then let volunteers refine the result. That gives contributors something to edit instead of a blank file.

A frequently overlooked part

Onboarding matters more than people think.

A simple TRANSLATING.md should answer:

Without that, every contributor invents a style guide from scratch.

The community model isn't one of the best types of translations for a closed product with no contributor culture. For open-source Django packages, though, it's often the only realistic way to support many languages without hiring translators.

The catch is discipline. Community translation without review is just distributed inconsistency.

6. Incremental Differential Translation

A common Django release pattern looks like this: a feature branch adds twelve user-facing strings, makemessages updates the .po files, and the translation step rewrites hundreds of old entries along with the new ones. The pull request gets bigger than it should be. Reviewers skim it. Locale noise hides the strings that changed.

Incremental differential translation avoids that mess. It processes only new, modified, or still-untranslated entries instead of sending the whole locale tree through the pipeline on every release.

For a Django repo, that fits how work lands. Teams ship small batches of UI copy, validation messages, emails, and admin text. The translation workflow should follow the same shape.

Basic flow:

django-admin makemessages -a
translatebot locale/ --only-missing
django-admin compilemessages

Or in a script:

#!/usr/bin/env bash
set -e

django-admin makemessages -a
translatebot locale/ --changed-only
django-admin compilemessages

The practical benefit is not just lower cost. It is cleaner engineering.

Small translation diffs are easier to review in Git. CI jobs finish faster because they touch fewer files. Rollbacks are safer because a bad translation update is tied to a specific code change, not mixed into a repo-wide locale refresh. If you have ever tried to debug a broken placeholder in a .po file after a bulk retranslation, you know why that matters.

This approach also exposes terminology drift earlier. If a developer changes "workspace" to "project space" in one template, the translation job surfaces that exact change instead of burying it inside a full-language regeneration. For jargon-heavy apps, that is where incremental workflows pair well with a business jargon translation process for product terminology.

What it gets right

Incremental translation keeps:

Batch translation feels simple at first, but pull requests with hundreds of unrelated locale edits often go unreviewed.

The teams that handle this well connect translation directly to extraction and only process entries whose source text changed. That setup is boring, which is exactly what you want in CI/CD. Translation infrastructure should behave like any other stable build step.

7. Glossary-Driven Translation

A glossary is the difference between "technically translated" and "internally consistent."

Without one, every system and every reviewer makes local decisions. "Workspace" becomes three different terms. "Billing" flips between noun and adjective forms. Your product starts sounding like multiple companies stitched together.

Why glossaries matter more than model choice

You can get decent output from several engines. You won't get consistent product language unless you define your terms.

That's especially true in software. Product teams invent words all the time. Feature names, role labels, workflow states, plan names. A generic translator has no way to know whether "team", "organization", and "workspace" are interchangeable in your app or three separate objects.

A repo-level glossary is helpful here. TranslateBot uses TRANSLATING.md for this style of setup, and the same idea works even if you use another workflow. If you translate jargon-heavy product text, this article on business jargon translation is directly relevant.

What to put in the file

Keep it lightweight and versioned with code.

For example:

# TRANSLATING.md

## Terms
- Workspace: product object, do not translate as "office"
- Thread: conversation within a channel
- Billing: use the noun form used for invoices and payment settings
- Pro: keep in English
- %(name)s, %s, {0}: never modify placeholders

## Tone
- Keep button labels short
- Use informal second person in user-facing UI
- Avoid overly formal support language

And if you want structure, add entries like:

This is one of the most underrated types of translations because it doesn't sound fancy. It's just terminology management. But in a real Django app, it prevents a huge amount of cleanup later.

8. Continuous Localization

Friday afternoon release. The feature is ready, tests are green, and then compilemessages fails because two new strings never made it through the translation workflow. Or worse, the build passes and production ships with English fallback text scattered across a localized settings page.

That problem usually starts earlier. Strings were added in code, makemessages was skipped, .po files drifted from the branch, and translation became a cleanup task instead of part of delivery. In a Django project, continuous localization means treating locale updates the same way you treat migrations or tests. Run extraction, update translations, validate the files, and make locale diffs visible in every PR.

A simple CI setup might look like this:

name: translations

on:
  pull_request:
  push:
    branches: [main]

jobs:
  i18n:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install deps
        run: pip install -r requirements.txt
      - name: Extract messages
        run: django-admin makemessages -a
      - name: Translate changed strings
        run: translatebot locale/ --changed-only
      - name: Compile messages
        run: django-admin compilemessages

That pipeline is enough for many teams. It catches missing message updates early, keeps .po files close to the code that introduced the strings, and reduces the ugly PR that rewrites half the locale directory right before release. The Docs as Code implementation link is useful if your team already manages technical content in Git and wants the same workflow for translations.

The CI angle makes more sense with a demo:

Critical CI Checks

Do not auto-merge translation commits unless the pipeline validates a few specific failure points:

The trade-off is straightforward. A stricter pipeline adds a few minutes to CI and forces developers to care about locale files earlier. In return, releases stop accumulating translation debt, and translators stop working from stale source text. In practice, that is the version that holds up.

9. Contextual Translation with Code Metadata

A surprising amount of translation quality comes down to one thing. Did the translator know where the string appears?

"Open" could be a verb or an adjective. "Charge" could mean billing, battery level, or an accusation. "Archive" might be a button label, a noun, or a backend concept. If you don't provide context, you're asking a person or a model to guess.

Use Django's built-in context features

Django already gives you tools for this.

from django.utils.translation import pgettext

label = pgettext("button action", "Archive")
status = pgettext("record state", "Archived")

That small bit of context prevents a lot of bad translations.

You can also help with translator comments:

# Translators: Shown on the billing page after a failed card payment.
message = _("Payment failed")

A diagram illustrating contextual translation with a computer preview and a magnifying glass showing developer notes.

What good context looks like

Useful metadata includes:

For machine-assisted workflows, the same idea applies. Put context into TRANSLATING.md, comments, or structured notes. The less a translator has to infer, the better the result.

"Archive" is not one string. It's several strings that happen to share spelling.

Contextual translation is one of the types of translations that looks optional right up until the first serious review pass. Then everyone realizes half the awkward phrasing came from missing metadata, not bad language skills.

10. Format-String Preservation Technical Translation

A translation can be linguistically fine and still break your app.

If a translated string drops %(name)s, mangles {0}, or edits HTML tags, you've turned a copy task into a runtime bug. This is the most technical part of translation work, and it's where sloppy workflows fail fast.

The rule

Treat placeholders and markup as code, not prose.

That means your translation process needs validation, not just proofreading.

Examples that must survive untouched:

msgid "Hello %(name)s"
msgstr "Bonjour %(name)s"
msgid "You have {0} new messages"
msgstr "Tienes {0} mensajes nuevos"
msgid "Click <strong>Save</strong> to continue"
msgstr "Cliquez sur <strong>Enregistrer</strong> pour continuer"

TranslateBot's format-string handling has 100% test coverage, according to the product information in the brief you provided. That's the kind of guarantee you want from any automation touching .po files.

What to automate

At minimum, add checks for:

A simple Python validation step can catch a lot:

import re

PLACEHOLDER_RE = re.compile(r"%\([^)]+\)s|\{[^}]+\}|%s")

def placeholders(text):
    return sorted(PLACEHOLDER_RE.findall(text))

assert placeholders("Hello %(name)s") == placeholders("Bonjour %(name)s")

This isn't a nice-to-have. Broken placeholders are one of the fastest ways to make localized releases look amateur.

10-Way Comparison of Translation Types

Approach 🔄 Implementation Complexity Resource Requirements ⭐📊 Expected Outcomes 💡 Ideal Use Cases ⚡ Key Advantages
Machine Translation (MT) with LLMs Moderate: integration + prompt engineering LLM/API access, token budget, glossaries, CI hooks High throughput and cost-efficiency; good contextual quality but needs review (⭐⭐⭐) Rapidly evolving apps, developer teams, high-volume localization Fast, scalable, inexpensive; preserves placeholders; CI-friendly
Human Translation (Professional Services) Low technical setup; high project management overhead Professional translators/agencies, CAT tools, QA reviewers Highest cultural and stylistic quality; reliable for sensitive content (⭐⭐⭐⭐⭐) Marketing, legal, brand-critical content, compliance documents Best nuance and tone; domain expertise and legal accuracy
Hybrid Translation (MT + Human Review) Moderate: orchestration of MT and post-editing LLM access + skilled post-editors, glossaries, review pipeline Balanced speed and quality; cost-reduced vs full human (⭐⭐⭐⭐) Large volumes needing quality, iterative product releases Combines automation speed with human nuance; cost-effective
Localization (L10n) Beyond Translation High: cross-functional engineering and research Localization engineers, designers, market researchers, legal Native user experience, higher adoption and market fit (⭐⭐⭐⭐) Global SaaS, consumer apps, fintech, international e-commerce Achieves strong market fit, builds trust, reduces support burden
Community-Driven Translation (Crowdsourcing) Low tooling complexity; requires active community management Volunteer translators, platform (Crowdin/Weblate), moderators Broad language coverage and engagement; variable quality (⭐⭐⭐) Open-source projects, nonprofits, community-led products Extremely cost-effective; authentic native input; community engagement
Incremental / Differential Translation Moderate: VCS integration and change detection CI/CD hooks, change-detection tooling, TranslateBot-like tools Lower cost and faster cycles by translating only diffs (⭐⭐⭐) Rapid-release teams, Django projects, frequent deployments Significant cost/time savings; smaller review diffs
Glossary-Driven Translation (Terminology Management) Low–Moderate: build and maintain glossary Product managers, translators, VCS, TM/CAT tools Consistent terminology across releases and languages (⭐⭐⭐) Technical products, brands, multi-team projects Ensures consistency; guides MT and human translators
Continuous Localization (CI/CD Integration) High: pipeline automation and QA gates DevOps, translation tooling, CI runners, automated tests Translations keep pace with code; reproducible builds (⭐⭐⭐) CI-first orgs, automated releases, DevOps-focused teams Automation keeps localization current; predictable costs
Contextual Translation (with Code Metadata) Moderate: capture and maintain context metadata Developer effort for notes/screenshots, context tooling, translators Higher accuracy and fewer queries; reduced rework (⭐⭐⭐) Complex UIs, ambiguous strings, high-quality localization needs Improves translator decisions; reduces ambiguity and edits
Format-String Preservation (Technical Translation) Moderate: validators and rigorous testing Automated QA tools, unit tests, engineering time Prevents runtime/formatting errors; enables safe automation (⭐⭐⭐⭐) Software localization, apps with placeholders, mission-critical apps Ensures placeholder safety; prevents production crashes

Build Your Django Translation Stack

A Django team ships a feature on Friday, merges the UI copy on Monday, and notices on Tuesday that half the new strings never made it into locale/fr/LC_MESSAGES/django.po. That is how translation debt starts. Not with strategy mistakes, but with small workflow gaps between makemessages, review, and deployment.

The practical fix is to build a stack around the kinds of strings you have. Admin labels, onboarding flows, billing emails, legal copy, and marketing pages should not all go through the same path. In a real project, one workflow for everything usually creates one of two problems. You spend too much reviewing low-risk strings, or you under-review high-risk ones.

For many Django teams, the stack is straightforward.

Use machine translation for high-volume product UI. That keeps the first pass fast and keeps .po files from becoming a manual bottleneck. Then make the process incremental. Translate only new or changed msgids, commit those diffs with the feature branch, and review them in the same pull request. That choice improves quality more than expensive tooling because reviewers can see the exact string changes in Git instead of comparing exported files in a separate portal.

Add a glossary early. A versioned TRANSLATING.md, or glossary data checked into the repo, gives translators and automation the same rules for product names, feature labels, and terms that should never drift between releases. In Django projects, that matters more than people expect because the same term often appears across templates, forms, emails, and JavaScript catalogs. If the glossary is not in version control, it usually falls behind the code.

Run localization in CI, not as a side task. makemessages, translation updates, validation, and compilemessages should be part of the normal build. If they are not, stale entries, fuzzy strings, and placeholder mistakes pile up fast. A release pipeline can catch that the same day. A spreadsheet-based process usually catches it after users do.

Human review still matters. Use it where mistakes are expensive or embarrassing: homepage copy, conversion paths, legal text, support flows, and strings with weak context. That split works well for small teams because it keeps cost focused on impact. The translators spend time where judgment matters, and the automation handles the repetitive volume.

Translation also is not the whole job. A complete .po file can still produce a bad localized experience if date formats, currencies, plural rules, RTL layout, or locale-specific punctuation are wrong. Developers usually feel this late, during QA, because the strings are translated but the interface still reads like a default English build with substituted text.

TranslateBot fits this workflow in a factual way. It works directly with Django .po files, translates only new or changed strings, uses a version-controlled glossary, and preserves placeholders with test coverage around format strings. For teams that want localization to behave like the rest of the codebase, that repo-first model is a better fit than copying strings into another SaaS dashboard.

The rule set is simple. Use automation for volume. Use human review for risk. Keep translations in Git. Treat locale changes like code changes.

If your team is still copy-pasting strings into browser tabs, fix that first. Once translation is attached to the same CLI and CI flow as the rest of the project, a lot of avoidable friction disappears.

If you need broader context on adjacent tooling, this overview of code language translator tools is a reasonable companion read.

If you want a developer-first way to handle Django localization, try TranslateBot. It translates .po files from the CLI, writes changes back to your locale files, preserves placeholders, and fits naturally into makemessages, compilemessages, Git review, and CI.

Stop editing .po files manually

TranslateBot automates Django translations with AI. One command, all your languages, pennies per translation.