Mobile app version of vmapp.org
Login or Join
Smith883

: Rewrite to SEO friendly URLs for language negotiation with type-map files on plain html files using .htaccess When visiting the website www.example.com/ the visitor should be redirected to the

@Smith883

Posted in: #Apache2 #CleanUrls #Htaccess #Multilingual #UrlRewriting

When visiting the website example.com/ the visitor should be redirected to the correct language version, e.g. example.com/en for english and example.com/es for spanish.

My current implementation only works when visiting example.com/index.var and redirects to example.com/index.en. Now I want to rewrite this to example.com/en/
My implementation is based on httpd.apache.org/docs/2.4/content-negotiation.html.
.htaccess

Options -MultiViews
RewriteEngine On
RewriteBase /
AddHandler type-map .var
LanguagePriority en es de
ForceLanguagePriority Fallback


index.var

URI: index; vary="language"

URI: index.en.html
Content-type: text/html
Content-language: en

URI: index.es.html
Content-type: text/html;charset=utf-8
Content-language: es

URI: index.de.html
Content-type: text/html;charset=utf-8
Content-language: de


Important: MultiViews are disabled

Looking forward to your great solutions.



to explain this a little more in detail...
Here's an example of my file structure:


File should be rewritten or redirected to
- index.var --> /
- index.en.html --> /en/
- index.es.html --> /es/
- about.var --> /about
- about.en.html --> /en/about
- about.es.html --> /es/about
- images/img_1.jpg --> /images/img_1.jpg
- images/logo.var --> /images/logo.png (not a file)
- images/logo.en.png --> /en/images/logo.png
- images/logo.es.png --> /es/images/logo.png


Rewriting of images and other resources is optional. It's only important to get rewriting of html files right.

The Apache Documentation is a working example of this (using content negotiation).

10.03% popularity Vote Up Vote Down


Login to follow query

More posts by @Smith883

3 Comments

Sorted by latest first Latest Oldest Best

 

@Smith883

I think I've found the solution on Apache's SVN repository. (I haven't tested it yet)

Configuration for Multilingual Site
Configuration for Multilingual Error Pages
Configuration with Languages and Encodings Setup

The implementation here uses the .html extension for type-map files instead of .var. That means, if you want to use html files with the extension .html instead of .html.en, you have to replace

AddHandler type-map .html

with

AddHandler type-map .var

like I did.

10% popularity Vote Up Vote Down


 

@Eichhorn148

I would use rewrite rules to issue 301 permanent redirects:

RewriteEngine on

# First handle the index.XX.html files
# where the language code is moved to the front directory
# and the index and html are removed
RewriteCond %{REQUEST_URI} !^/?([a-z]{2})/
RewriteRule ^/?(.*/)?index.([a-z]{2}).html$ // [L,R=301]

# Then handle other file.XX.html files
# where the language code is moved to the front directory
# the file name is preserved, but the html is removed
RewriteCond %{REQUEST_URI} !^/?([a-z]{2})/
RewriteRule ^/?(.*).([a-z]{2}).html$ // [L,R=301]

# Handle all other file.XX.xyz
# where the language code is moved to the front directory
# and the file name and extension are preserved
RewriteCond %{REQUEST_URI} !^/?([a-z]{2})/
RewriteRule ^/?(.*).([a-z]{2}).([a-z]+)$ //. [L,R=301]


This detects a two character language code using the regular expression ([a-z]{2}). You could instead using something like (en|es|de) with a specific list of supported languages. Doing so could reduce mistakes based on two digit codes used for something other than language (like maybe a gzipped javascript file: .js.gz.) It would also allow you to expand the rules to include country info if needed (like en-us.)

All the rules have a RewriteCond that makes sure they don't apply in the language subdirectories. That should help prevent infinite loops or other problems

The rules start with /? which consumes any leading slash so the rules can be used either in .htaccess or in an Apache .conf file.

The first rule makes the directory path preceding index optional using a question mark in the section (.*/)?. It allows that rule apply to the root index.XX.html files.

I didn't put in a rule for the .var files because it sounds like you already have something in place for them. You would need to continue to handle those files as you do now.

I tested these rules on my local Apache server by putting them in .htaccess and hitting the site with curl. They seem to do the right thing:

$ curl -s --head 'http://example.com/index.en.html'
HTTP/1.1 301 Moved Permanently
Location: example.com/en/
$ curl -s --head 'http://example.com/index.es.html'
HTTP/1.1 301 Moved Permanently
Location: example.com/es/
$ curl -s --head 'http://example.com/about.en.html'
HTTP/1.1 301 Moved Permanently
Location: example.com/en/about
$ curl -s --head 'http://example.com/about.es.html'
HTTP/1.1 301 Moved Permanently
Location: example.com/es/about
$ curl -s --head 'http://example.com/images/logo.en.png'
HTTP/1.1 301 Moved Permanently
Location: example.com/en/images/logo.png
$ curl -s --head 'http://example.com/images/logo.es.png'
HTTP/1.1 301 Moved Permanently
Location: example.com/es/images/logo.png

10% popularity Vote Up Vote Down


 

@Megan663

I would just do this in PHP. I'm not sure how to do it in htaccess.

I would make index.php :

<?php
header("Status: 200 OK");
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
switch ($lang){
case "fr":
//echo "PAGE FR";
include("index_fr.php");//include check session FR
break;
case "it":
//echo "PAGE IT";
include("index_it.php");
break;
case "en":
//echo "PAGE EN";
include("index_en.php");
break;
default:
//echo "PAGE EN - Setting Default";
include("index_en.php");//include EN in all other cases of different lang detection
break;
}
?>


Or if you want the redirect you can do:

<?php
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
switch ($lang){
case "en":
header('Location: www.example.com/en/', true, 302);
exit;
case "es":
header('Location: www.example.com/es/', true, 302);
exit;
case "de":
header('Location: www.example.com/en/', true, 302);
exit;
default:
//echo "PAGE EN - Setting Default";
include("index_en.php");//include EN in all other cases of different lang detection
break;
}
?>

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme