MODX Multi-language Setup (Babel/LangRouter)
MODX does not have built-in multi-language support — it uses combination of contexts and specialized packages. Two main approaches: Babel (associates resources of different contexts) and LangRouter (language prefix routing).
Architecture: Contexts + Babel
Each language is separate context. Babel establishes "links" between corresponding resources of different contexts.
Context: web (Russian, main)
├── Home (id: 1)
├── About (id: 5)
Context: en (English)
├── Home (id: 100) ← linked to id:1
├── About Us (id: 105) ← linked to id:5
Babel Installation
# Package Manager → Babel
Babel System Settings:
babel.sites: web,en,de (context keys comma-separated)
babel.contextPrefix_en: en/ (URL prefix)
babel.contextPrefix_de: de/
babel.contextPrefix_web: (empty = main language without prefix)
Language Switcher via BabelLinks
[[!BabelLinks?
&tpl=`@INLINE
<a href="[[+url]]" hreflang="[[+cultureKey]]"
class="lang-switch [[+active:is=`1`:then=`lang-switch--active`]]">
[[+cultureKey:upper]]
</a>
`
&activeCls=`active`
]]
BabelLinks automatically creates links to related resources in other contexts.
LangRouter: Routing without Contexts
LangRouter is alternative without contexts. Single context, different languages stored in TV or via lex-files.
# Package Manager → LangRouter
[[!LangRouter?
&default=`ru`
&langs=`ru,en,de`
]]
LangRouter adds /en/, /de/ prefixes to URL and switches cultureKey.
Lexicons (Interface Translation)
For translating static template text — MODX lexicons:
// core/lexicon/ru/default.inc.php
$_lang['btn_more'] = 'Learn More';
$_lang['contact_us'] = 'Contact Us';
$_lang['read_more'] = 'Read More';
Output in template:
[[%btn_more? &namespace=`mysite` &topic=`default`]]
hreflang for SEO
[[!BabelLinks?
&tpl=`@INLINE <link rel="alternate" hreflang="[[+cultureKey]]" href="[[+url]]">`
&toPlaceholder=`hreflang`
]]
<head>
[[+hreflang]]
<link rel="alternate" hreflang="x-default" href="[[++site_url]]">
</head>
Babel vs LangRouter vs Manual Contexts
- Contexts + Babel — standard for large sites. Full content separation, templates, settings.
- LangRouter — simpler for small sites, fewer settings, limited flexibility.
- Manual — only for simple cases (2 languages, small site).
Timeline
Setting up two languages via Babel with switcher and hreflang — 2–3 days.







