Language "home" page redirect does not work after update

Hi all,

after an update, I have a problem with the “home” page of the second language.
Kirby 3.5 → 3.7
PHP 7.4 → 8.1

My default language is DE and the URL “www.example.de” correctly shows the content of the page width the blueprint “home”.

The second language EN should do the same: “www.example.de/en” should show the content of the page “en/home” width blueprint “home”.
But there shows up an 404 error, the page itself “www.example.de/en/home” is working. Every page after /en/ works fine: “www.example.de/en/whatever”.
Before the update, it was working.

I removed the home page of EN, but even the copy of the home DE variant doesn’t work.
For testing, I added another language: CH. Don’t work the same way.

In the kirby config, I added this, but this doesn’t change anything:

'urls' => [
        'de' => 'www.example.de',
        'en' => 'www.example.de/en',
],

This is my EN config:

return [
    'code' => 'en',
    'default' => false,
    'direction' => 'ltr',
    'locale' => [
        'LC_ALL' => 'en_US'
    ],
    'name' => 'Englisch',
    'translations' => [
		...
    ],
    'url' => '/en'
];

And the DE config:

return [
    'code' => 'de',
    'default' => true,
    'direction' => 'ltr',
    'locale' => [
        'LC_ALL' => 'de_DE'
    ],
    'name' => 'Deutsch',
    'translations' => [
		...
    ],
	'url' => '/'
];

I don’t know how to fix this. :frowning: Has someone any idea about this problem?

Which version are you testing? The latest 3.7.5?

Do you have any routes in place that might interfere?

It was 3.7.1, but now it’s updated to 3.7.5. Still the same.

Here is my full config:

return [
	'url' => 'https://example.de/',
    'debug' => true,
	'languages' => true,
	'home' => 'home',
	'scssNestedCheck' => true,
	'routes' => [
		[	
			'pattern' => 'sitemap.xml',
			'action'  => function() {
				$pages = site()->pages()->index();
				$ignore = kirby()->option('sitemap.ignore', ['error']);
				$content = snippet('sitemap', compact('pages', 'ignore'), true);
				return new Kirby\Cms\Response($content, 'application/xml');
			}
		],
		[
			'pattern' => 'sitemap',
			'action'  => function() {
				return go('sitemap.xml', 301);
			}
		],
		[
            'pattern' => '(:any)',
            'action'  => function($uid) {
                $page = page($uid);
                if(!$page) $page = page('redirects/' . $uid);
                if(!$page) $page = site()->errorPage();
                return site()->visit($page);
            }
        ],
        [
            'pattern' => 'redirects/(:any)',
            'action'  => function($uid) {
                go($uid);
            }
        ]
	]
];

I think the error happens because of this route.

Year, now it works! :slight_smile:

You are right, I don’t need this part of the routes. The last one does the job alone, because the redirects are important :smiley:

Thank you, texnixe for the very fast help!

Hello again,

the solution worked last week. The EN page was there, and the redirects worked either.

But now the redirects aren’t working anymore. The page is now live, but I don’t change anything in the code!

The goal from the code:

		[
            'pattern' => '(:any)',
            'action'  => function($uid) {
                $page = page($uid);
                if(!$page) $page = page('redirects/' . $uid);
                if(!$page) $page = site()->errorPage();
                return site()->visit($page);
            }
        ],
        [
            'pattern' => 'redirects/(:any)',
            'action'  => function($uid) {
                go($uid);
            }
        ]

is that a link like “/redirect/one-page” goes automatically to “/one-page”, but there only is a 404 error.

Here Routing 101 - Remove part of the URL - #4 by texnixe in this post you recommend the same code, texnixe.

But why does this not work in the newest kirby version? :frowning:

Yes, a redirect needs the two parts, but you are in a multilanguage site where you need the language key:

ok, I understand the problem, but I can’t find a solution, should it be something like that?

		[
            'pattern' => '(:any)',
            'language' => 'de',
            'action'  => function($language, $uid) {
                $page = page($uid);
                if(!$page) $page = page('redirects/' . $uid);
                if(!$page) $page = site()->errorPage();
                return site()->visit($page);
            }
        ],
        [
            'pattern' => 'redirects/(:any)',
            'language' => 'de',
            'action'  => function($language, $uid) {
                go($uid);
            }
        ]

Is it a problem, that my default language DE has no “/de” in the URLs? There is only the “/en”.
It should only work for DE because on the EN page are no redirects.

Does someone know what is wrong in my Code? :slight_smile:

I don’t know how to combine the language- and the overwrite-pattern, so that everything works.

I think the problem is actually the first route, which is probably disabling our built-in routes.

I just tested this in a similar setup and can reproduce the issue. I would have expected that if I set a language key in the route array, that the route would be ignored for other languages.

Edit: But I now also tested this with 3.5.8 and 3.6.6 and getting the same error, so it doesn’t seem to be due to some change regarding routing.

What you can do to fix this, is change the first route to:

       [
            'pattern' => '(:any)',
            'language' => 'de',
            'action'  => function($language, $uid) {
                $page = page($uid);
                if(!$page) $page = page('redirects/' . $uid);
                if ($page) {
                    return site()->visit($page);
                }
                $this->next();
            }
        ],

I changed the first route, and now it is working. :slight_smile:

Thank you very much for your help!