Independent page tree structure for every language

I’m evaluating Kirby for an upcoming website that will be available in three languages. But as I understand, the default way that Kirby handles multi-language websites, is that there is only one page tree structure. That is, the default language is the master that defines the page tree structure. Then, each page can optionally be translated in other languages. If a page is missing a translated language, the default language is shown. This is what I understand is the default behavior of Kirby in a multi-language setup. Correct me if I’m wrong here.

This way to handle a multi-language site is not what my client want. The client wants an independent page tree structure for every language. For example they may want to have a specific page only available in the german version of the site. And another page only available in the swedish version of the site.

This is the prerequisites that the client has:

  • The users should only need one login each, to access all language specific pages.
  • Independent page tree structure for every language
  • Possibility to choose the desired language version in the panel, to only show pages in that language.
  • Possibility to create a new page in one language that is not shown in the other languages.
  • Url:s in the form of sub folders:,,

And for me as a developer, my prerequisites are these:

  • One installation of Kirby.
  • Blueprints should be translatable as usual.
  • Formatting of dates and currencies should be handled according to current language both in backend and frontend.

Could someone point me in the right direction if this is possible?

That is absolutely correct.

The only option to prevent this behavior I can think of, would be to use different folders for each language. But in that case, you would loose the language functions (translating blueprints, switching languages in the Panel etc.)

While you can use redirects and filters to prevent the default fallback behavior in a standard setup in the frontend, I don’t see a way to fulfill all your requirements, particularly [quote=“ola, post:1, topic:6203”]
Possibility to choose the desired language version in the panel, to only show pages in that language.

Would a possible solution be to use a multi-site setup somehow? Each site would then have a specific language specified. The only drawback would then be that there will be three different login for each author that needs access to all three language versions? In that case, that might be an acceptable drawback.

That could in fact work, however, I’m not really familiar with multi-site setups.

I tried this multi-site setup but could not get it to work with different languages. But then again, I’m not that of an experienced Kirby developer yet. So I might have missed something essential.

Looks like I have to go back to WordPress for this project. :cry:

I don’t think you even need a multi-site setup for this. What about a directory structure like this:


Only one login, separate file structure, URLs are correct.
The language.txt files would be used for global information that is normally placed inside site.txt.

This is a hack and probably more work than with the standard setup, but I think this could work.

But as I already mentioned above, with this kind of setup, you loose the language features, e.g. locale settings, blueprint translations, etc.

Blueprint translations are still possible as they are based on the user language in the Panel, not the multilang feature.

Regarding locale settings etc.: Yes, definitely. But you can work around those, e.g. by getting the current language code from the URL in a plugin and setting custom options based on that.

Thanks @lukasbestle and @texnixe. I will definitely try this out. Yes it sounds like a hack, but a valid one. I will let you know how it went after I had a chance to experiment with this idea.

Always nice to see other swedish people here! :slight_smile:

This is my take on it:

Folder structure:


Then for the default language I would probably use a route to force a root url structure.

Then it would look like this:

When using WordPress back in the old days, I solved many sites the similar way and I think it’s fine.

Maybe that’s already suggested by @texnixe or @lukasbestle.

However, I also saw your suggestion in this topic, but from my point of view Kirby can already handle this case well enough.

1 Like

Yep, that’s exactly what I meant above. :slight_smile:

Ja det är alltid trevligt med lite svenskar @jenstornell :slight_smile:

Thanks for all help here. I have played around a little with this and got a working solution. As you suggested I have a directory structure with a root page for all languages.

The problem I encountered was that I was unable to use the custom language variables for string translations. This needed the multi language mode to be activated, which I don’t wanted in the first place. But in the source code I found the code that loaded these language files, so I copied them to my site.php file and loaded them manually.

After writing some code that extracts the language code from the url, my site.php looks like this:


$kirby = kirby();

// Map of languages used:
$languages = array(
	'en' => 'en_US',
	'de' => 'de_DE',
	'sv' => 'sv_SE'

// Get paths from url:
$paths = str::split($kirby->path, '/');

// Extract possible language code from first path. I.e: 'en' from
if (count($paths) && isset($languages[$paths[0]])) {
	$language = $paths[0];
} else {
	$language = 'sv'; // Fallback language

// Path for the language file:
$path = $kirby->roots()->languages() . DS . $language;

// Load .php file if it exists:
if(f::exists($path . '.php')) include_once($path . '.php');

// Load .yml file and set as language variables if it exists:
if(f::exists($path . '.yml')) l::set(data::read($path . '.yml', 'yaml'));

// Set correct locale for php date and time functions:
setlocale(LC_ALL, $languages[$language]);

This works. But please correct me if I did something wrong or if it’s possible to simplify this even more.

I guess that language variables are not loaded at all on a single language installation. Therefor you need to do it yourself like you did. If this works I don’t find anything wrong with that.

Personally I would try to wrap it up as a plugin. I have not tested but in my mind this might work:

  1. Copy the code you have to like plugins/my-plugin/my-plugin.php.
  2. Add this to your site.php file: kirby()->plugin('my-plugin');

If it works it will force load your plugin before other things are loaded. It will run only once even if you force load it like this.

As I said, it’s untested but if it works it would be a “nice” hack. :slight_smile:

1 Like

As I wrote before, you shouldn’t do this. If you force load a single plugin before the plugins get loaded by Kirby, the other plugins won’t get loaded automatically anymore. Force loading just works to load in dependencies from plugins.

Oh, I forgot about that. :slight_smile: Maybe just keep it like it is then, or use include instead, maybe to a file outside the plugin folder somewhere.

Once we have support for the language registry, loading language files in single-language sites will work out of the box anyway. :slight_smile:


It seems to me that Ola problem is pretty related to another topic awaiting Kirby 2.5 to be solved. Once it’s solved, there will be no need for hacks. Ola would be able to use the same structure for all langauges, benefits from all nice language features, and filter menu/contents by language as it was possible before Kirby 2.3. What is not translated will be ignored in other languages.
The actual problem is that Kirby requieres the default language .txt file to be present in each page’s folder to work correctly. Free us from this constraint, and everything would become easy.

this topic is nearly one year old, and i stumpled upon it, while looking for how to have a multilang-site with independent pages/page trees per language.
is this still best practice?

Well, the way multi-languages sites work hasn’t changed, so I think this is still the easiest way to achieve this.