Je hebt een Django-app gebouwd. Hij werkt, gebruikers schrijven zich in, en nu wil je mensen bereiken die geen Engels spreken. Het probleem is meteen duidelijk zodra je ernaar kijkt: Django's internationalisatieframework is uitstekend in het extraheren van vertaalbare strings, maar doet absoluut niets om de vertalingen in te vullen. Dat deel is aan jou.
Als je een solo-ontwikkelaar bent of een team van twee personen, kan de kloof tussen makemessages en een volledig vertaalde app enorm aanvoelen. Ik loop door de realistische opties, leg uit waarom de meeste niet werken voor kleine teams, en laat een workflow zien die vertaling verandert van een wekenlange klus naar een commando van twee minuten.
De traditionele opties (en waarom ze pijn doen)
Optie 1: Kopieer-plak vanuit Google Translate
De meest voorkomende eerste poging. Je opent je .po-bestand, kopieert elke msgid naar Google Translate, plakt het resultaat terug als msgstr, en herhaalt. Voor elke string. In elke taal.
Een typische Django-app heeft 200-500 vertaalbare strings. Als je naar vijf talen vertaalt, zijn dat 1.000-2.500 kopieer-plakcycli. Zelfs als elk ervan maar 30 seconden duurt, kijk je naar 8-20 uur geestdodend werk. En dat is voordat je de opmaakfouten, kapotte placeholders en inconsistente terminologie herstelt die er onvermijdelijk insluipen.
Erger nog, je moet het opnieuw doen in de volgende sprint wanneer je nieuwe strings toevoegt.
Optie 2: Professionele vertalers
Professionele vertaling kost doorgaans $0,10 tot $0,25 per woord. Een Django-app met 500 strings van gemiddeld 8 woorden komt neer op ongeveer 4.000 woorden. Bij $0,15/woord is dat $600 per taal, of $3.000 voor vijf talen.
Voor een door VC gefinancierde startup is dat een afrondingsfout. Voor een solo-ontwikkelaar die $9/maand per gebruiker vraagt, kan het je volledige omzet voor het kwartaal opslokken.
Optie 3: Fiverr en freelance marktplaatsen
Je kunt vertalers vinden op Fiverr voor $20-50 per taal. Sommigen zijn oprecht vakkundig. Velen plakken simpelweg je tekst in Google Translate en rekenen je daarvoor. Je eindigt met dezelfde kwaliteit als Optie 1, plus een extra ronde communicatie en een week wachten.
Optie 4: Crowdin, Transifex of Weblate
Deze platformen zijn krachtig, maar ze zijn ontworpen voor projecten met toegewijde vertaalteams. De setup-overhead (repositories synchroniseren, vertaalgeheugen configureren, toegang voor bijdragers beheren) is overkill wanneer je de enige persoon op het project bent. Maandelijkse abonnementen beginnen bij $30-150/maand voor betaalde abonnementen, en zelfs gratis abonnementen vereisen dat je nóg een derde-partij-integratie onderhoudt.
Optie 5: Alles in ChatGPT plakken
Dit werkt eigenlijk verrassend goed qua kwaliteit. Je plakt de inhoud van je .po-bestand in ChatGPT of Claude, vraagt om vertalingen, en krijgt redelijke resultaten. Het probleem is dat het niet schaalt. Je moet handmatig de onvertaalde strings extraheren, de prompt formatteren, het antwoord terugparsen naar .po-formaat, en batching afhandelen wanneer je contextlimieten overschrijdt. Het werkt één keer. Het valt uit elkaar als herhaalbare workflow.
De automatiseringsaanpak
Wat als de hele vertaalstap één enkel commando was? Dat is het idee achter TranslateBot, een open-source Django-managementcommando dat je .po-bestanden leest, onvertaalde strings naar een AI-provider stuurt, en de vertalingen terugschrijft in het juiste formaat.
Zo stel je het in.
Stap 1: Installeer TranslateBot
uv add --dev translatebot-django
Of met pip:
pip install translatebot-django
Voeg het toe aan je geïnstalleerde apps:
# settings.py
INSTALLED_APPS = [
# ...
'translatebot_django',
]
Stap 2: Configureer je AI-provider
Voeg twee instellingen toe:
# settings.py
import os
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"
TranslateBot werkt met OpenAI, Anthropic Claude, Google Gemini, en meer dan 100 andere modellen via LiteLLM. Het ondersteunt ook DeepL als dedicated vertaalbackend.
Stap 3: Maak een TRANSLATING.md (optioneel maar aanbevolen)
Een TRANSLATING.md-bestand in je projectroot geeft de AI context over je applicatie. Dit is wat generieke machinevertaling onderscheidt van vertalingen die daadwerkelijk bij je product passen:
# Translation Context
## About This Project
A personal finance tracker for freelancers. Users track invoices,
expenses, and tax obligations.
## Tone
- Friendly and informal
- Use "du" in German, "tu" in French
- Keep financial terms precise
## Terminology
- "invoice" = "Rechnung" (German), "facture" (French)
- "dashboard" = keep as English loanword in all languages
- "freelancer" = keep as English loanword in German
Dit bestand wordt meegestuurd met elk vertaalverzoek, zodat de AI consistent de juiste toon en terminologie gebruikt.
Stap 4: Vertaal
python manage.py makemessages -l de -l fr -l nl -l es -l ja
python manage.py translate
python manage.py compilemessages
Drie commando's. Dat is alles. TranslateBot vindt alle onvertaalde strings in al je .po-bestanden, vertaalt ze in batches, en schrijft de resultaten terug. Standaard worden alleen lege entries vertaald, dus het opnieuw uitvoeren van het commando na het toevoegen van nieuwe strings vertaalt alleen de nieuwe.
Hoe dit eruitziet in de praktijk
Hier is een realistische sprint-workflow voor een solo-ontwikkelaar die vijf talen ondersteunt:
Maandag: Je bouwt een nieuwe feature. Je voegt een paar nieuwe vertaalbare strings toe met gettext() en {% trans %} terwijl je bezig bent.
from django.utils.translation import gettext_lazy as _
class InvoiceView(View):
def post(self, request):
# New string added during development
messages.success(request, _("Invoice sent successfully."))
Voor het committen: Je voert drie commando's uit:
python manage.py makemessages -a --no-obsolete
python manage.py translate
python manage.py compilemessages
Het translate-commando detecteert de nieuwe onvertaalde entries en vertaalt alleen die. Als je 5 nieuwe strings hebt toegevoegd en 5 talen ondersteunt, maakt het 25 vertalingen in één API-call. Het hele proces duurt minder dan een minuut.
Je commit je code, templates, en bijgewerkte .po/.mo-bestanden samen. Vertalingen zijn onderdeel van je normale ontwikkelflow, geen apart project.
Bekijk een preview voor je commit
Als je vertalingen wilt zien voordat ze naar schijf worden geschreven, gebruik dan de dry-run modus:
python manage.py translate --dry-run
Dit toont elke vertaling in de terminal zonder bestanden te wijzigen.
De kostenvergelijking
Hier wordt automatisering moeilijk te weerleggen.
| Aanpak | 500 strings, 5 talen | Tijd | Terugkerende kosten |
|---|---|---|---|
| Handmatig kopiëren-plakken | Gratis | ~40 uur | ~8 uur/sprint |
| Professionele vertalers | ~$3.000 | 1-2 weken | ~$600/sprint |
| Fiverr-vertalers | ~$100-250 | 3-7 dagen | ~$50/sprint |
| Crowdin/Transifex | $30-150/maand | Setup: uren | Doorlopend |
| TranslateBot + GPT-4o-mini | ~$0,05 | ~2 minuten | ~$0,01/sprint |
| TranslateBot + DeepL Free | $0 | ~2 minuten | $0 |
Een kleine tot middelgrote Django-app met ongeveer 500 vertaalbare strings kost doorgaans minder dan $0,01 per taal met gpt-4o-mini. Voor de meeste solo-projecten dekt de gratis laag van DeepL (500.000 tekens/maand) alles zonder kosten.
Om duidelijk te zijn: AI-vertalingen zijn niet perfect. Goedkope menselijke vertalingen ook niet. Het verschil is dat AI-vertalingen bijna niets kosten, direct beschikbaar zijn, en opnieuw kunnen worden uitgevoerd wanneer je maar wilt.
CI-integratie: lever nooit onvertaalde strings
Een van de meest nuttige patronen die ik als solo-ontwikkelaar heb gevonden, is het toevoegen van een vertaalcontrole aan CI. TranslateBot bevat een check_translations-commando dat faalt als een .po-bestand onvertaalde of fuzzy entries heeft:
# .github/workflows/ci.yml
jobs:
translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv python install
- run: uv sync --frozen
- name: Install gettext
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends gettext
- name: Check translations
run: uv run python manage.py check_translations --makemessages
Als je een nieuwe {% trans %}-tag toevoegt in een template en vergeet translate uit te voeren, vangt CI het op:
locale/de/LC_MESSAGES/django.po: 1 untranslated, 0 fuzzy
locale/fr/LC_MESSAGES/django.po: 1 untranslated, 0 fuzzy
CommandError: Translation check failed
Dit verandert vertalingen van iets dat je moet onthouden in iets dat je niet kunt vergeten.
Praktische tips
Begin met twee of drie talen. Je hoeft niet op dag één in 15 talen te lanceren. Kies de talen waar je de meeste gebruikers hebt of de grootste adresseerbare markt. Duits, Frans en Spaans dekken veel af voor Europese markten.
Laat moedertaalsprekers kritieke strings reviewen. AI-vertalingen zijn goed genoeg voor de meeste UI-tekst, maar de kop van je landingspagina en je onboarding-flow verdienen een menselijk oog. Vraag een vriend, een gebruiker, of iemand in een communityforum om 10 minuten te besteden aan het reviewen van de meest zichtbare strings.
Gebruik dry-run voordat je overschrijft. Als je ooit alles opnieuw moet vertalen (bijvoorbeeld na het bijwerken van je TRANSLATING.md met betere terminologierichtlijnen), bekijk dan eerst een preview van de wijzigingen:
python manage.py translate --overwrite --dry-run
Bewaar TRANSLATING.md in versiebeheer. Het is onderdeel van de vertaalconfiguratie van je project. Wanneer je terminologie of toonrichtlijnen bijwerkt, zal de volgende translate-uitvoering die wijzigingen weerspiegelen voor nieuwe strings.
Vertaal per app wanneer nodig. Als je alleen strings in één app hebt gewijzigd, kun je de vertaling beperken:
python manage.py translate --app billing
Van weken naar minuten
Django's internationalisatieframework is een van de beste in elk webframework. De tooling voor makemessages, locale-directories en compilemessages is volwassen en betrouwbaar. Het enige ontbrekende stuk was de vertaalstap zelf. Dat was voorheen het dure, trage deel.
Met TranslateBot wordt de workflow:
- Schrijf code met
gettext()en{% trans %}zoals normaal - Voer
makemessagesuit om strings te extraheren - Voer
translateuit om vertalingen in te vullen - Voer
compilemessagesuit om te compileren - Commit alles samen
Voor een solo-ontwikkelaar betekent dit dat lokalisatie niet langer een project is dat je plant voor "ooit." Het is iets dat je vandaag kunt doen, in de tijd die het kost om een kopje koffie te zetten.
TranslateBot is open source en beschikbaar op PyPI en GitHub. Installeer het, voer het commando uit, en zie je app in een nieuwe taal binnen enkele minuten.