James James - 1 month ago 20
Apache Configuration Question

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

Answer

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.