Drupal Translations Guide
Comprehensive guide for Drupal multilingual websites, translation workflows, and localization best practices.
Source: https://raw.githubusercontent.com/theodorosploumis/notes/refs/heads/master/drupal/translations.md
Overview
Drupal translations involve multiple layers:
- Interface translation: UI strings (t(), trans())
- Configuration translation: Settings, labels, descriptions
- Content translation: Nodes, taxonomy terms, blocks
- Entity translation: Custom entities with multilingual support
Translation Steps for Drupal Projects
Initial Setup
- Install profile with required modules
- Enable additional languages (non-English)
- Configure language negotiation at
/admin/config/regional/language
Translation Workflow
Interface Translation UI (
/admin/config/regional/translate)- Add translations for interface strings
- Search and translate individual strings
Configuration Translation (
/admin/config/regional/config-translation)- Translate settings forms and configuration
- Also accessible via "Translate" tab on each config form
Export Translations
- Export PO files per language:
drush locale:export LANGCODE - Store in
mymodule/translations/mymodule.LANGCODE.po - Define path in
mymodule.info.yml:translation path: translations/mymodule.LANGCODE.po
- Export PO files per language:
Config Translation Export
- Export config YML files with translations
- Copy files from
config/sync/language/*to module'sconfig/install/language/*
Entity/Content Translation
- Use CSV import for bulk content translation
- Manual translation through UI for menu items, blocks, nodes, taxonomy
Translation Storage Matrix
| Type | Configuration | Twig Templates | Module Strings | Drupal Entities |
|---|---|---|---|---|
| Source | PO, YML | PO | PO | CSV |
| Location | YML: install/language/LANGPO: translations/ folder |
translations/ folder |
translations/ folder |
Custom migration module |
| Translation Server | Yes (PO, POTX only) | Yes | Yes | No |
Essential Drush Commands
# Install profile with specific language
drush si MYPROFILE --locale de -y
# Core locale commands
drush locale:check
drush locale:update
drush locale:export LANGCODE
drush locale:import LANGCODE PATH_TO_PO_FILE
# Examples
drush locale:import de modules/custom/MY_MODULE/translations/MY_MODULE.de.po
drush locale:import nl modules/custom/MY_MODULE/translations/MY_MODULE.nl.po
# Config language negotiation
drush cget system.site
drush config:set language.negotiation url.prefixes.el el
Recommended Translation Modules
Essential
- tmgmt - Translation Management Tool (comprehensive workflow)
- potx - Translation template extractor (PO/POT generation)
- l10n_client - On-page translation interface
- babel - Content translation workflow enhancement
Specialized
- config_import_locale - Config translation import
- config_translation_access - Access control for config translation
- potion - Drush-based PO file management
- multilingual_audit - Audit multilingual setup
- tmgmt_spreadsheet - Spreadsheet-based translation workflow
- translation_extractor - Automated string extraction
Utilities
- interface_string_stats - Translation statistics
- l10n_tools - Localization helper tools
- locale_override - Override specific translations
- simple_entity_translations - Simplified entity translation UI
Translation Workflow with External Services
Process A: Translate via Spreadsheet
Translator → Google Sheets (XLS) → CSV → PO (for non-entities)
Process B: Translate via Translation Service
Translator → l10n_server (or Service) → Translate (manual or API) → Export PO → Import to /translations/PROJECT.LANGCODE.po
Translation Spreadsheet Columns
Standard columns for collaborative translation (e.g., Google Sheets):
| Column | Purpose |
|---|---|
| location | Source location of string |
| source | English string to translate |
| target | Translated string |
| suggestion | Fuzzy/auto-suggestions |
| context | Unique key for disambiguation |
| comments | Notes for translators |
| updated | Last modified date |
| author | Latest editor |
Key API Hooks and Functions
- locale.api.php - Interface translation hooks
- hook_locale_translation_projects_alter - Alter translation projects
- config_translation.api.php - Config translation API
- hook_config_translation_info_alter - Alter config translation metadata
- i18n group - Internationalization utilities
- Translation class - Core translation handling
Complete Solution Requirements
When evaluating translation solutions, check for:
- Export/import formats (PO, CSV, XLIFF, YML, XLSX, MO, REST)
- Sync/update capabilities
- Bulk translation cleanup options
- Template export (POTX)
- Translation status reports
- On-page/in-place editing
- Fuzzy suggestions
- Translation user roles
- Database storage for translation metadata
- Translation merging capabilities
- Context-based overrides
- SEO validation for multilingual
- Admin language toggle per user
External Tools & Services
Translation Services
- localize.drupal.org - Official Drupal localization server
- drupal.org/project/l10n_server - Self-hosted translation server
- poeditor.com - Online translation management
- weblate.org - Open source translation platform
- localizejs.com - JavaScript/on-the-fly translation
Desktop & Online Utilities
- poedit.net - Desktop PO file editor
- mlocati.github.io/jsgettext - Online PO/POT/MO converter
Common Translation Issues
Known Core Issues
- Configuration language overwritten during module install (#2905295)
- Translated Config Override default behavior (#2993984)
- String context and location filters (#2123543)
- Cannot delete source strings in D8+ (#2503893)
- META: Modernize Locale module (#3215707)
Best Practices
Structure
- Plan multilingual architecture early
- Define content vs interface translation needs
- Set up language negotiation strategies
Development
- Use t() consistently in code
- Provide context for ambiguous strings
- Extract templates regularly with potx
Workflow
- Separate interface and content translation workflows
- Use CSV for bulk content translation
- Keep PO files in version control
Deployment
- Export/import translations before deployment
- Test with all enabled languages
- Verify RTL support if needed