Multilingual websites with MODX

Sun Jul 10, 2022 Share on:

MODx has many extras which makes building multilingual websites easy. At Inside Creative, our preferred method is the Babel Extra. Unlike Lingua, Babel uses multiple MODx contexts to manage different languages; this gives us the freedom to design and redesign different elements of the website to better target customers' needs. This article will cover the groundwork needed to get up and running with the MODx Babel Extra on your site using SEO Friendly URLs.

Getting started with Babel Multilingual MODx websites

Before downloading Babel, you'll need to set up a few things in your MODx manager. Firstly start by creating a new context for each language you plan on translating your website into. In our example, the main WEB context will be our English translation, and we'll create two new contexts, one for Spanish and another for Thai.

NOTE: Be sure to enter the language ISO 639-1 Code into the Content Key and give the context an appropriate name. Once you save your new context, the site tree will refresh, and your new context will appear.

Configuring the context settings

Once we have the new contexts in place, we need to create a few settings to make everything work. Firstly create a new home resource in the new contexts then add the following settings into all your contexts excluding the mgr context. (Our English translation).

NOTE: If you want your primary language (English in our case) to forgo the /en/ (cutlureKey) in the URL make sure that both the base_url and site_url don't contain the ISO lang code.

cultureKey: es (ISO 639-1 Code)
base_url: /es/
http_host: (Make sure to remove the www.)
site_start: 1 (ID of context home resource)

Ensure the right permissions have been granted to anonymous users

On newer versions of MODx when you create a new context, it should automatically be added to the Anonymous user group with Load Only access. It's good practice to check that these permissions have been granted to each context otherwise the user won't be able to access the translated content.

Changing the context based on the cultureKey setting

There are two main ways of changing the context depending on the cultureKey, for this tutorial we'll be installing the MODx Extra XRouting which will handle everything for us. You can read through their getting started tutorial here. However, we've written this tutorial to compliment the Extra so everything you have done/ will do should be compatible with XRouting. If you want to create your own version of the context switcher plugin then use the code below:


if($modx->context->get('key') != "mgr"){
    /* grab the current langauge from the cultureKey request var */
    switch ($_REQUEST['cultureKey']) {
        case 'es':
            /* switch the context */
        case 'th':
            /* switch the context */
            /* Set the default context here */
    /* unset GET var to avoid
     * appending cultureKey=xy to URLs by other components */

Set the plugin event to listen for OnHandleRequest, and make sure you mark the plugin as active.

Go ahead and install the XRouting Extra and Babel Extra using the MODx package manager, when you install Babel it will ask you to enter the context keys (the field should already contain your context keys, i.e. web,es,th. But make sure all your translation context keys are listed). If you are translating an existing website, then you'll want to enter the IDs of the Template Variables that need to be synchronised.

Setting up the server

As you may have noticed we build all our MODx websites on MODx Cloud which uses NGINX, if you use an apache server you'll need to edit your htaccess file:

NGINX Config
set $lang en;

# choose the language that appears first in the accept_language header
if ($http_accept_language ~* "(en|es|th)") {
  set $lang $1;

location ~ ^/$ {
  rewrite ^ $lang/ redirect;

location ~ ^/(en|es|th) {
  # redirect favicon.ico and assets/* requests to site root
  rewrite ^/(en|es|th)/(favicon.ico|assets.*)$ /$2 redirect;
  # main Babel rewrite
  rewrite ^/(en|es|th)/(.*)$ /?cultureKey=$1&q=$2 break;
  # MODX rewrite
  try_files $uri $uri/ @modx-rewrite;

location / {
  try_files $uri $uri/ @modx-rewrite;
htaccess config
RewriteEngine On
RewriteBase /

# The Friendly URLs part
# detect language when requesting the root (/)
RewriteCond %{HTTP:Accept-Language} !^en [NC]
RewriteRule ^$ en/ [R=301,L]
RewriteRule ^$ es/ [R=301,L]
RewriteRule ^$ th/ [R=301,L]
# redirect all requests to /en/favicon.ico and /de/favicon.ico
# to /favicon.ico
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en|es|th)/favicon.ico$ favicon.ico [L,QSA]
# redirect all requests to /assets*
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en|es|th)/assets(.*)$ assets$2 [L,QSA]
# redirect all other requests to cultureKey 
# to index.php and set the cultureKey parameter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|es|th)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]

You should now be able to access your translations by changing the URL to /es/, /th/ etc.

Now that you have your translations up and working have a read of the official Babel documentation on creating new translations, linking translated resources and adding translation links.