James
James

Reputation: 739

Multi language custom 404 htaccess rules causing redirect loop

I'm working on a multi language website where I need to set up a custom 404 page for each language. I've got the following rules in .htaccess which don't quite work right:

RewriteCond %{REQUEST_URI} !^/(ie)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/ie/404/

RewriteCond %{REQUEST_URI} !^/(se)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/se/404/

RewriteCond %{REQUEST_URI} !^/(nl)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/nl/404/

#last rule becomes default
RewriteCond %{REQUEST_URI} !^/(en)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/uk/404/

RewriteRule ^([a-z]{2})/404(/)?$ index.php?controller=utils&method=view404&lang=$1 [L]
RewriteRule ^([a-z]{2})/404.html$ index.php?controller=utils&method=view404&lang=$1 [L]

I think the issue may be with the ! in the RewriteCond, however removing this didn't help. If I visit domain.com/4t3409t0 (a page which doesn't exist) this matches the last RewriteCond and redirects to domain.com/uk/404 (which actually works).

However if I try a URL such as domain.com/ie/wfnwio it attempts to redirect to domain.com/ie/404 (as it should) and I get stuck in a redirect loop.

So it looks like when the last RewriteCond is met the rewrite works but for any others they fail.

I just need to set the ErrorDocument URL for each language, the functionality for redirecting non existing content to 404 already exists.

Thanks for any input,

James

Upvotes: 2

Views: 3146

Answers (3)

Kenan Murad
Kenan Murad

Reputation: 1

I got an idea from this comment. In .htacces file:

ErrorDocument 404 "<script>window.location.href='/error.php?page='+window.location.href;</script>" 

In error.php (in root directory) :

<?php
$lg="en";  // default 404 page language
$langs=array("az","tr","ru","en");

if(isset($_GET['page'])){
    $page=$_GET['page'];
    foreach($langs as $lang){ 
    if(strpos($page,"lang=".$lang)!==false) { $lg=$lang; break; }
    }
} 
echo '<meta http-equiv="refresh" content="0;URL=/index.php?controller=utils&method=view404&lang='.$lg.'" />'; 
exit;

Upvotes: 0

James
James

Reputation: 739

I think the issue I had was with the RewriteCond being incorrect. However I found a workaround as PHP stores the language in a session variable.

ErrorDocument 404 http://www.domain.com/404/

RewriteRule ^404(/)?$ index.php?controller=utils&method=view404 [L]
RewriteRule ^([a-z]{2})/404(/)?$ index.php?controller=utils&method=view404&lang=$1 [L]
RewriteRule ^([a-z]{2})/404.html$ index.php?controller=utils&method=view404&lang=$1 [L]

My workaround simply uses domain.com/404 as the default, which then sets the language via session if possible, or loads the UK 404 page if not.

If the language variable is set in the query string it is passed using the 2nd and 3rd rewrite rules.

Upvotes: -2

zx81
zx81

Reputation: 41838

I would suggest replacing all of that with something like this:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(ie|se|nl)/ $1/404 [R=404,L]

Explanation

  • The three conditions check that the requested file or folder does not exist
  • The rule checks that the requested url starts with one of the three countries then a /, captureing the country code to Group 1
  • It redirects to Group1/404, e.g. ie/404 with a 404 code

Upvotes: 3

Related Questions