Multilingual (multicontext) with MODX is complicated

Previously, for multilingual support, I simply used BABEL and a plugin that switched contexts based on the cultureKey
I added the following to .htaccess

# Redirects le chiamate di /en/favicon a quella favicon.ico
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(it|en|es|de|fr)/favicon.ico$ favicon.ico [L,QSA]
# Come sopra per gli assets da /en/assets/ a assets/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(it|en|es|de|fr)/assets(.*)$ assets$2 [L,QSA]
# Redirects tutte le altre richieste da /en/ a normale cambiando la culturkey
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(it|en|es|de|fr)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]

I would apply for every context other than web, English (German)
cultureKey en (de)
base_url {base_url}en/ ({base_url}de/)
site_url {site_url}en/ ({site_url}de/)
site_start 1 (69)

in the head I inserted

<base href="[[!++site_url]]" />
...
<link rel="image_src" href="[[!++site_url]]default.jpg" />
...
<link rel="stylesheet" href="[[!++site_url]]assets/css/style.css" />
...
<script  src="[[!++site_url]]assets/js/script.js?v=04042023"></script>

If I inserted a TV image into the template, I would retrieve it with [[*imgTv]] by including it as the src (relative path) and I would insert all other relative paths (e.g., assets/…).
Everything was working; the only problem was with images in tinyMCE RTE that didn’t work on pages in contexts other than web (I was using TVs).
I tried to evolve and looked for other solutions. The information on Babel and various routing options is not very explanatory, and the old links I had on Babel, which explained with examples and snippets, redirect to the general page.
I decided to always use Babel but to evolve towards smartRouting, and I couldn’t get anything to work. :grinning_face:
My settings are what I have read and the following


But on the pages outside the web context, CSS and JS are not loaded, images (*imgTv) with a relative path neither)
Whether I include the initial .htaccess lines or omit them.
Is there any kind soul who can explain to me, even with examples, in detail what settings to configure to make Babel work with smartRouting?
Creating a multilingual (multicontext) site with Babel and smartRouting shouldn’t be that difficult, so perhaps providing a detailed example would help many, maybe even to be included in the explanations in MODX Docs.

thanks in advance

The ‘problem’ with multi-context sites in MODX is, that there are like 4 different methods to (basically) achieve the same, and every methods requires different settings or extras or changes to .htaccess, which makes it more confusing than it is.


In your case, I think the only thing that has to be changed is how you link CSS/JS and images files in your page.

Basically you have to apply step 8 from the LangRouter documentation:

Include the static files from the assets folder in your installation with [[++assets_url]]path/to/static_file, i.e. <link href="[[++assets_url]]css/site.css" rel="stylesheet"> or <img src="[[++assets_url]]images/whatever.jpg" … >. You could use [[++base_url]]path/to/static_file, if your assets are not located inside the assets folder.

So instead of

use <link rel="stylesheet" href="[[++assets_url]]css/site.css" />


Alternatively, you could adjust the .htaccess file and add the part back that deals with requests to the assets/ folder:

...

# The part that rewrites requests to files in the 'assets' folder,
# so that a request to https://mysite.com/de/assets/someimage.jpg
# is rewritten to https://mysite.com/assets/someimage.jpg
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(it|en|es|de|fr)/assets(.*)$ assets$2 [L,QSA]

# The Friendly URLs part (default rule that is necessary for friendly URLs to work)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Thanks as usual!

Only with the changes to .htaccess it doesn’t work, I don’t know why.

asset_url would be a new system setting to add, pointing to https://miosito.it/assets/, right?
But in this case, files in the root wouldn’t be visible, like the miosito.webmanifest. I could create a new system setting root_url = https://miosito.it/ and use it everywhere, or am I wrong?
<link rel="stylesheet" href="[[++root_url]]assets/css/site.css" />
<img src="[[++root_url]][[*imgTV]]" />
<link rel="manifest" href="[[++root_url]]sito.webmanifest" crossorigin="use-credentials">

so I would only need to put the redirect for the favicon in .htaccess

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(it|en|es|de|fr)/favicon.ico$ favicon.ico [L,QSA]

which is not in the head but present, right?
or, as usual, did I not understand anything? :grinning_face:

The system setting [[++assets_url]] should already exist on the system (usually with the value /assets/) which then creates a URL like /assets/css/site.css which is a relative URL based on the document root (because of the leading /).

There is a difference between these two image tags:

<head>
    <base href="https://mysite.com/de/">
    ...
</head>
<body>
    <img src="assets/image.png">
    <img src="/assets/image.png">
    ...
</body>

The first requests https://mysite.com/de/assets/image.png, the second https://mysite.com/assets/image.png.


I guess you could also create a new setting (like [[++root_url]]) if you prefer that.

Without creating a new system setting, assets_url was not working, I don’t know why.
However, with assets_url, I cannot link elements in the main root like webmanifest, while with root_url I can.
Does the name root_url cause problems?
Finally, regarding link_tag_scheme, I always set it to https, on langRouter it says to set it to -1, but it works with https as well, is that just a coincidence?
What should I test to confirm this besides the links [[~id]]?

Maybe check the requests in the “Network” tab of the developer tools (in the browser), to see what the actual paths are that get requested (for the CSS, JS, images files).

It should also be possible to just add a / at the beginning → href="/sito.webmanifest"

This name is not used by MODX, so there shouldn’t be a problem.


-1 generates a relative URL. https an absolute URL.
I guess if <base href="[[!++site_url]]" /> is set correctly on the page, then the final result is the same.

Thank you, as soon as I’m done and everything works, I’ll post my solution while waiting for the advice you will give me.:blush:

It works.
In my infinite ignorance, however, I haven’t understood why, in non-web contexts, /site.webmanifest works and /assets/image/someimage.jpg does not.

without new sistemsetting asset_url, [[++assets_url]]css/.. result→ /assets/css/…
but without https://miosito.it/ not function

EDIT: sorry I saw your modification afterward, which clarified more things for me, including the question above.

In light of what you wrote, can I use

<link rel="stylesheet" href="[[++assets_url]]css/miostyle.css" />

in place of

<link rel="stylesheet" href="[[!++site_url]]assets/css/miostyle.css" />

even on sites with only web content (not multilingual)?

Talking about image-type TV
in template on sites with only web content (not multilingual) I need to use

<img src="[[*imgTV]]" />

in template on sites with multicontext I need to use

<img src="/[[*imgTV]]" />

right?

For TinyMCE RTE and image in multicontext when I add images from assets

in web context it’s ok in other context prepend / to the path I see in the field (even if on the site appears ../assets), Is it a fair solution since it works?

When you set up a multi-lingual site like you did, with the base_url context-settings /en/, /de/, you introduce these “virtual subfolders” /de/ and /en/.
These “virtual subfolder” are necessary for the URLs of the MODX resources, so that the plugin can correctly determine the context (of the requested resources).
But these “virtual subfolders” can’t be in the URLs of the files that are located in the assets folder (that is shared by all the contexts).

One way to achieve this, is to set the <base> tag URL, so that it includes the “virtual subfolder”.
Then you use relative URLs (without the leading /) for the links to other pages/resources (so that the path is relative to the whole value of the <base> tag).
And for other files you use a relative URL (with the leading /), so that the path is relative to the site root (of the value in the <base> tag).

<head>
    <base href="https://mysite.com/en/"> <!-- includes "virtual subfolder" -->
    ...
    <link rel="stylesheet" href="/assets/site.css" />
</head>
<body>
    <a href="some-parent/some-page.html">some page</a>
    ...
</body>

I guess there are other ways to achieve the same. For example using absolute URLs (with https://...) for everything, or removing the “virtual subfolder” from the <base> tag and instead adding the base_url before every link to other pages/resources.

As usual, the are different ways to achieve something in MODX and there is no “right way” to do it. Find something that works for your site/use-case.


On a site with only the “web” context, you don’t have these “virtual subfolders”.
When your <base> tag is <base href="https://mysite.com/">, then relative URLs with or without the leading slash (/) are functionally the same.
What kind or URL (absolute, root-relative, current-directory-relative) you use, is then more kind of a personal preference.

On bended knee, I thank you infinitely