Multi language/domain setup with RealURL - revised


typo3 realurl speakung urls search engine friendly urls

The development of RealURL has made great progress and after the latest comment on an older article I decided to review the setup of a multilingual site with TYPO3.

The setup must meet two major objectives: language switching by domain, a proper language switching menu with properly encoded page paths.

Note, that this setup follows a very basic approach which don't include any configuration for extensions or special requirements.


Affter Dmitry's comment I saw the need to publish a follow up article to "TYPO3 multi language & multi domain site with RealURL and language menu".

Dmitry had objections regarding the performance and maintability of my approach and this are two other important goals for website development with TYPO3.

Furthermore, RealURL supports a new feature _DOMAINS, which allow a domain dependent configuration for the language parameter. This is a feature which is already built in since 2009 but was buggy in some RealURL versions so I decided to implement the workaround with TypoScript conditions.


Like the first version, let's set some conditions for the setup:

  1. within one page tree every page has a unique page title in every language 
  2. every page in a page tree has an alternative page language 
  3. at root level, all domains must be created as domain records which should be available for the specific page tree
  4. the main domain records (no redirects) must not have set the "Always prepend this domain in links" option
  5. the root level page must have set the "Is root of website" option in the page properties
  6. for this sample setup the default language (sys_language_uid = 0) is english

Furthermore, I assume that you've configured your webserver and virtual host environment correctly, so the TYPO3 installation is able to "answer" the request for the specific domains. (e.g. ServerAlias directive for Apache)

RealURL Setup

For the RealURL setup I've read the following articles (mentioned by Dmitry in his comment, thank you again!):

For the sample setup, I build a clean and fresh RealURL configuration. This time, not starting with the _DEFAULT configuration array, but with the proper domain names. I did exactly the same like Dmitry, but leave the preVars array empty. 

// RealURL multi domain setup
$tx_realurl_config = array(
	'init' => array(
		'enableCHashCache' => true,
		'appendMissingSlash' => 'ifNotFile',
		'enableUrlDecodeCache' => true,
		'enableUrlDecodeCache' => true,
		'emptyUrlReturnValue' => '/',
	'preVars' => array(
	'postVarSets' => array(
		'_DEFAULT' => array(
	'pagePath' => array(
		'type' => 'user',
		'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
		'spaceCharacter' => '-',
		'languageGetVar' => 'L',
		'expireDays' => 3,

$TYPO3_CONF_VARS['EXTCONF']['realurl'] = array(
	'typo3-ml.local' => $tx_realurl_config,
	'typo3-ml-de.local' => $tx_realurl_config,
	'typo3-ml-it.local' => $tx_realurl_config,

$TYPO3_CONF_VARS['EXTCONF']['realurl']['typo3-ml.local']['pagePath']['rootpage_id'] = 1;
$TYPO3_CONF_VARS['EXTCONF']['realurl']['typo3-ml-de.local']['pagePath']['rootpage_id'] = 1;
$TYPO3_CONF_VARS['EXTCONF']['realurl']['typo3-ml-it.local']['pagePath']['rootpage_id'] = 1;


$TYPO3_CONF_VARS['EXTCONF']['realurl']['_DOMAINS'] = array(
	'encode' => array(
			'GETvar' => 'L',
			'value' => '0',
			'useConfiguration' => 'typo3-ml.local',
			'urlPrepend' => 'http://typo3-ml.local'
			'GETvar' => 'L',
			'value' => '1',
			'useConfiguration' => 'typo3-ml-de.local',
			'urlPrepend' => 'http://typo3-ml-de.local'
			'GETvar' => 'L',
			'value' => '2',
			'useConfiguration' => 'typo3-ml-it.local',
			'urlPrepend' => 'http://typo3-ml-it.local'
	'decode' => array(
		'typo3-ml.local' => array(
			'GETvars' => array(
				'L' => '0',
			'useConfiguration' => 'typo3-ml.local'
		'typo3-ml-de.local' => array(
			'GETvars' => array(
				'L' => '1',
			'useConfiguration' => 'typo3-ml-de.local'
		'typo3-ml-it.local' => array(
			'GETvars' => array(
				'L' => '2'
			'useConfiguration' => 'typo3-ml-it.local'

TypoScript #1: TYPO3 multi language configuration

After that, I wrote down the TypoScript configuration for multi language websites (see doc_l10ndocguide

config {
  // [ ... ]

  // configuration as documented in doc_l10nguide
  linkVars = L

  // setup for L=0 (english)
  htmlTag_langKey = en-US
  locale_all = en_US.utf8
  language = en
  sys_language_uid = 0
  sys_language_mode = content_fallback
  sys_language_overlay = 1
  baseURL = http://typo3-ml.local/

// setup for L=1 (german)
[globalVar = GP:L = 1]
config.htmlTag_langKey = de-DE
config.locale_all = de_DE.utf8
config.language = de
config.sys_language_uid = 1
config.baseURL = http://typo3-ml-de.local/

// setup for L=2 (italian)
[globalVar = GP:L = 2]
config.htmlTag_langKey = it-IT
config.locale_all = it_IT.utf8
config.language = it
config.sys_language_uid = 2
config.baseURL = http://typo3-ml-it.local

TypoScript #2: The language switcher

At last, I added a simple language menu. This time I don't spend time for searching a suitable solution in the web but simply used the language menu documented in doc_l10nguide!

The only things which were adjusted here are the language labels. It's only a proof of concept. Feel free to adjust the setup to your needs!

lib.langMenu = HMENU
lib.langMenu {
  special = language
  special.value = 0,1,2
  special.normalWhenNoLanguage = 0
  1 = TMENU
  1 {
    // Normal link to language which exists
    NO = 1
    NO.allWrap = |*| | *  |*| |
    NO.linkWrap = <b style="background-color : grey"> | </b>
    NO.stdWrap.setCurrent = English || Deutsch || Italiano
    NO.stdWrap.current = 1

    // Current language selected
    ACT < .NO
    ACT.linkWrap = <b style="background-color : red"> | </b>

    // Language which is NOT available
    USERDEF1 < .NO
    USERDEF1.linkWrap = <span style="background-color : yellow"> | </span>
    USERDEF1.doNotLinkIt = 1

Last but not least...

...some hints for your own setup:

  • Check and double-check your domain names in RealURL config! During testing I have to fix typos again and again (maybe it was too late at night ;))
  • Rename the TYPO3 distribution htaccess from _.htaccess to .htaccess
  • Leave the preVars section empty! Otherwise RealURL respectively TYPO3 tries to find the L param in the first parts of the URL!

As a convenience I added my TYPO3 content setup as a *.t3d import file and the RealURL setup file.


comments powered by Disqus