LangRouter issues

I have a multi-language setup with the two contexts web and en. I setup everything according to the LangRouter documentation.

So I set these system settings:

babel.contextDefault      = web
langrouter.contextDefault = web
link_tag_scheme           = -1

My contexts have these settings:

             web    en
base_url     /      /
cultureKey   de     en
site_url     {url_scheme}{http_host}{base_url}{cultureKey}/   (on both)
site_start   1      6

Now to my issue:

When my browser is set to german (de)

  • and I access domain.tld I see the german version as intended
  • and I access domain.tld/de/ I also see the german version as intended
  • and I access domain.tld/en/ I see the english version as intended

However if my browser is set to english

  • and I access domain.tld/en/ I see the english version as intended
  • and I access domain.tld/de/ I see the german version as intended
  • and I access domain.tld I see an ERROR: The page isn’t redirecting properly

My error log is spammed with these errors, probably because some redirect loop is happening:

Show errors
(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 162) Unhandled request:
REQUEST_URI:   /
REDIRECT_URI:  
QUERY_STRING:  
q:             
Context:       web
Site start:    1
(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 186) contextmap: array(2) {
  ["de"]=>
  string(3) "web"
  ["en"]=>
  string(2) "en"
}

(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 186) Detected culture key: string(2) "en"

(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 186) Detected context key: string(2) "en"

(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 162) Culture key not found in URI:
REQUEST_URI:   /
REDIRECT_URI:  
QUERY_STRING:  
q:             
Context:       en
Site start:    6
(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 198) Redirect to https://domain.tld/

It claims “Culture key not found in URI” but that’s kind of the point, shouldn’t it redirect to the language of my browser or atleast to the default context?

Thanks for any help, I’m obviously not understanding this fully yet.

MODX 3.0.4
PHP 8.2
LangRouter 1.4.2-pl
Babel 3.1.1-pl

Here the code should redirect to https://domain.tld/en/ (and not to https://domain.tld/).
Why is the cultureKey missing from the URL?

As far as I can tell, the code uses the context setting site_url for the redirect:

But site_url should contain the cultureKey according to your settings → {url_scheme}{http_host}{base_url}{cultureKey}/.

That’s what I’m wondering as well. I have no clue…

I manually cleared the cache and double checked all the settings again, but I can’t find the issue.

Maybe @jako has an idea?


I don’t know if that’s related, but when I open the Babel CMP i see no resources and I get this error in the log:

(ERROR @ /core/src/Revolution/modX.php : 1784) Unable to load processor for action "mgr/resource/getMatrixList", it does not exist as an autoloadable class that extends \MODX\Revolution\Processors\Processor, and also not as a file in "/core/components/babel/processors/mgr/resource/getMatrixList.class.php"
1 Like

It’s not. This is (again) a problem with capitalization.
See this PR:

If you request the site url without a subdirectory, the logged messages look almost right (when REQUEST_URI is /). They are shown because you have activated langrouter.debug in the system settings.

(ERROR in LangRouter @ /core/components/langrouter/src/LangRouter.php : 198) Redirect to https://domain.tld/

This line should have a culture key included in the url according to the context settings.

If not, you first should clear at least the system settings cache and the context settings cache (maybe manually by deleting the core/cache/system_settings and core/cache/context_settings folder).

I already tried hard clearing the cache (and just did so again with the mentioned folders) but no success.

As long as my browser language is set to English and I try access just domain.tld (which is the german web context) I get the error. Any other constellation works fine like I mentioned above.


I remembered when I first tried to set this up, I had an additional de context created until I realised I could just use the web one for the german site as I didn’t know how to redirect from the web to one of the separate languages anyway. I since then deleted that context and it’s also not mentioned in any of the settings anymore, but could this have interefered in some way?

Any more ideas?

In the file core/cache/context_settings/en/context.cache.php, what’s the value of “site_url”? Does it contain the language /en/?

array (
    ...
    'site_url' => 'https://somedomain.com/en/',
  ),

Yes it does:

array (
    'base_url' => '/',
    'cultureKey' => 'en',
    'site_start' => '6',
    'site_url ' => 'https://domain.tld/en/',
  )

The web context ( core/cache/context_settings/web/context.cache.php) also has the de added:

array (
    'base_url' => '/',
    'cultureKey' => 'de',
    'site_start' => '1',
    'site_url ' => 'https://domain.tld/de/',
  )

It’s still a mystery to me, why it doesn’t work.

If you add this log line

$this->langrouter->logMessage("CONTEXT = {$this->modx->context->get('key')} | SITE_URL = {$this->modx->context->config['site_url']}");

here in the code

is the output correct? (CONTEXT = en | SITE_URL = https://domain.tld/en/)

I get this:

core/components/langrouter/src/Plugins/Events/OnHandleRequest.php : 69) PHP warning: Undefined array key "site_url"

Interesting.

Does

$this->langrouter->logMessage("CONTEXT = {$this->modx->context->get('key')}");

at least show the correct context? (CONTEXT = en)

Sorry dummy me had the debug mode temporarily disabled for some other stuff. The output was there also with the previous line, but still no site_url showing, it’s just empty:

CONTEXT = en | SITE_URL = 

I assume your code context->config['site_url'] is on purpose different to the very similar code used on line 67: context->getOption('site_url')? Or could this be the reason no site_url is showing?

getOption() has a fallback and returns the system-setting if no context-setting is found with that key. I wanted to see if there is a context-setting (as should be according to the cache file).


Are there other extras installed that run on events like OnMODXInit or OnHandleRequest and potentially interfere with the process? Maybe “ClientConfig” or similar?
Can you (temporarily) disable their plugins to see if that changes anything?

I don’t see any of the plugins running on those system events (Is there a global check to see on which event something is happening, instead of having to check the plugins one by one?)

Just to be sure I disabled all plugins, cleared the cache but still the error persists.

Here is a list of all installed extras:

  • Ace 1.9.3-pl
  • Babel 3.1.1-pl
  • CrossContextsSettings 1.2.4-pl
  • emo 1.8.9-pl
  • FormIt 5.0.1-pl
  • Guzzle7 7.8.0-pl
  • LangRouter 1.4.2-pl
  • MIGX 3.0.2-beta1
  • pdoTools 3.0.2-pl
  • TinyMCE Rich Text Editor 2.0.9-pl
  • UpgradeMODX 2.3.5-pl

I also tested this on Firefox and Chrome, both times with the same result: If the browser language is set to English, I get an error when visiting https://domain.tld. When it’s set to german it works fine.

There is a space sign after site_url in the according key in the context cache file output, you have posted above. That should be the issue. You have to create the context setting again without the space in the key or change the key with a direct database access.

1 Like

Wow… so sorry for wasting everyones time :sweat_smile:

Great eye @jako and thank you nonetheless for the tireless help @halftrainedharry!

How did you create the setting key? Maybe this should be posted as a bug in the Revo repository. The key should be trimmed, since the space at the end is hard to detect.

I think I used CrossContextSettings and I might have just copy & pasted it in there, so that’s maybe where the extra space was coming from.

Then I will create an issue in CrossContextsSettings :crazy_face:

1 Like

CrossContextSettings uses the MODX core processor. And this processor does not trim the key.