Autodetect browser language & redirect
Autodetect browser language & redirect
I use 3 languages on my website, so it would be nice to use the following javascript to autodetect user's browser language and redirect him to the right language.
Default language is Dutch (nl), and I also have an English and French version which are located in the usual /en and /fr folders.
German is also mentioned, but this should go to the English version, as I tried to specify in the script.
---------------------------------------------------------------------------------------
Here's the script:
<script>
/*
Browser Language Redirect script- By JavaScript Kit
For this and over 400+ free scripts, visit http://www.javascriptkit.com
This notice must stay intact
*/
//Enter ISO 639-2 letter Language codes to detect (see: http://www.w3.org/WAI/ER/IG/ert/iso639.htm):
var langcodes=new Array("nl", "en", "fr", "de", "default")
//Enter corresponding redirect URLs (last one is for default URL):
var langredirects=new Array("index.php", "/en/", "/fr/", "/en/", "index.php")
var languageinfo=navigator.language? navigator.language : navigator.userLanguage
var gotodefault=1
function redirectpage(dest){
if (window.location.replace)
window.location.replace(dest)
else
window.location=dest
}
for (i=0;i<langcodes.length-1;i++){
if (languageinfo.substr(0,2)==langcodes){
redirectpage(langredirects)
gotodefault=0
break
}
}
if (gotodefault)
redirectpage(langredirects[langcodes.length-1])
</script>
---------------------------------------------------------------------------------------
This seems to work, except for the 'Default' language.. I have tested the script by setting my browser to first English and then French language. The script reacts as it should, when it's approached with my browser in English, it redirects to http://www.mywebsite.com/en and the English version appears. Same done for French, also successful.
However, when I open the website with my browser set to Dutch, the url switches to http://www.mywebsite.com/index.php and loops infinite without loading anything.
It probably has something to do with the way I have configured the script, where I defined "index.php" as the default. Could there be a solution or is this script only possible if all 3 languages are in separate folders, and not structured as usual in cmsimple (default language directly on the root and extra languages in separate folders).
Hope someone is interested in the script and can help my out.
Thanks in advance.
Default language is Dutch (nl), and I also have an English and French version which are located in the usual /en and /fr folders.
German is also mentioned, but this should go to the English version, as I tried to specify in the script.
---------------------------------------------------------------------------------------
Here's the script:
<script>
/*
Browser Language Redirect script- By JavaScript Kit
For this and over 400+ free scripts, visit http://www.javascriptkit.com
This notice must stay intact
*/
//Enter ISO 639-2 letter Language codes to detect (see: http://www.w3.org/WAI/ER/IG/ert/iso639.htm):
var langcodes=new Array("nl", "en", "fr", "de", "default")
//Enter corresponding redirect URLs (last one is for default URL):
var langredirects=new Array("index.php", "/en/", "/fr/", "/en/", "index.php")
var languageinfo=navigator.language? navigator.language : navigator.userLanguage
var gotodefault=1
function redirectpage(dest){
if (window.location.replace)
window.location.replace(dest)
else
window.location=dest
}
for (i=0;i<langcodes.length-1;i++){
if (languageinfo.substr(0,2)==langcodes){
redirectpage(langredirects)
gotodefault=0
break
}
}
if (gotodefault)
redirectpage(langredirects[langcodes.length-1])
</script>
---------------------------------------------------------------------------------------
This seems to work, except for the 'Default' language.. I have tested the script by setting my browser to first English and then French language. The script reacts as it should, when it's approached with my browser in English, it redirects to http://www.mywebsite.com/en and the English version appears. Same done for French, also successful.
However, when I open the website with my browser set to Dutch, the url switches to http://www.mywebsite.com/index.php and loops infinite without loading anything.
It probably has something to do with the way I have configured the script, where I defined "index.php" as the default. Could there be a solution or is this script only possible if all 3 languages are in separate folders, and not structured as usual in cmsimple (default language directly on the root and extra languages in separate folders).
Hope someone is interested in the script and can help my out.
Thanks in advance.
Re: Autodetect browser language & redirect
Hi Nicky,
just try the following changes:
Basically it's sufficient to handle "nl" as the default, and index.php is not necessary (results in nicer URLs). But this results in the redirect loop also. It would be possible to modify the script to not recurse, but please note the following remark.
I see several problems with this approach:
So you can try it as it is. Just put the following code to userfuncs.php:
That may be a working replacement for the JavaScript script.
Christoph
just try the following changes:
Code: Select all
var langcodes=new Array("en", "fr", "de", "nl")
var langredirects=new Array("/", "/en/", "/fr/", "/en/", "/")
I see several problems with this approach:
- If JavaScript is disabled or not available in the browser, nothing happens. Amongs others this is a problem with bots, which usually do not evalutate JavaScript.
- If JavaScript is enabled, the redirect takes place after the requested page was delivered. This is a bit wasteful.
- It's not possible to manually override the language redirection. That's okay, if the site is fully localized (i.e. all pages are translated to all languages, and are up-to-date); otherwise the visitor should be able to switch the language manually.
- Deep links from outside are lost; the visitor always lands on the start page of his language.
- To detect the client's language only the first to letters of navigator.language resp. navigator.userLanguage are taken into account. navigator.language may take the value of the Accept-Language HTTP Header (this is at least so for recent Chrome and Firefox). But this value is actually more complex than just specifying the desired language. There can be several languages given, each with a weight, which to prefer, and it's even possible, that the preferred language is not the first in the list. Consider e.g. this Accept-Language header: "de;1.0,fr:0.9" (could be someone from the Saarland; a native German speaker, who speaks French very good). He will be redirected to "en" even if he would be happy to read the site in French.
- The user can't navigate the site. If he browses to /?Second_page, he'll be redirected to / (i.e. the start page)
So you can try it as it is. Just put the following code to userfuncs.php:
Code: Select all
<?php
function Autolang_languages()
{
global $pth, $cf;
$languages = array();
$dn = $pth['folder']['base'];
$dh = opendir($dn);
while (($fn = readdir($dh)) !== false) {
if (is_dir($dn . $fn) && preg_match('/^[A-z]{2}$/', $fn)) {
$languages[] = $fn;
}
}
if ($dh) {
closedir($dh);
}
sort($languages);
array_unshift($languages, $cf['language']['default']);
return $languages;
}
function user_language()
{
if (isset($_COOKIE['autolang_choice'])) {
$language = $_COOKIE['autolang_choice'];
} else {
$language = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); // TODO
}
return $language;
}
function Autolang_menu()
{
global $pth, $sl;
$items = array();
$languages = Autolang_languages();
foreach ($languages as $i => $language) {
$fn = $pth['folder']['flags'] . $language . '.gif';
$label = is_readable($fn)
? tag('img src="' . $fn . '" alt="' . $language . '"')
: "[$language]";
$items []= '<a href="' . CMSIMPLE_ROOT . ($i > 0 ? "$language/" : '')
. '?autolang_force=' . $language . '">' . $label . '</a>';
}
return implode(' ', $items);
}
function Autolang()
{
global $sn, $sl;
if (isset($_GET['autolang_force'])) {
setcookie('autolang_choice', $_GET['autolang_force'], 0, CMSIMPLE_ROOT);
header("Location: $sn", true, 301);
exit();
}
$languages = Autolang_languages();
$userLang = user_language();
if (!$userLang) {
return;
}
if (!in_array($userLang, $languages)) {
$userLang = $languages[0];
}
if ($userLang != $sl) {
header("Location: $sn$userLang/", true, 303);
exit;
}
}
Autolang();
Christoph
Christoph M. Becker – Plugins for CMSimple_XH
Re: Autodetect browser language & redirect
Hello Christoph,
I dug up this thread and tried your workaround.
Conclusion:
Your PHP snippet is not quite complete:
Something is still missing to intercept an infinite loop.
Could you please take another look and add it?
Thank you very much!
I dug up this thread and tried your workaround.
Conclusion:
Your PHP snippet is not quite complete:
Code: Select all
<?php
function Autolang_languages()
{
global $pth, $cf;
$languages = array();
$dn = $pth['folder']['base'];
$dh = opendir($dn);
while (($fn = readdir($dh)) !== false) {
if (is_dir($dn . $fn) && preg_match('/^[A-z]{2}$/', $fn)) {
$languages[] = $fn;
}
}
if ($dh) {
closedir($dh);
}
sort($languages);
array_unshift($languages, $cf['language']['default']);
return $languages;
}
function user_language()
{
if (isset($_COOKIE['autolang_choice'])) {
$language = $_COOKIE['autolang_choice'];
} else {
$language = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); // TODO
}
return $language;
}
function Autolang_menu()
{
global $pth, $sl;
$items = array();
$languages = Autolang_languages();
foreach ($languages as $i => $language) {
$fn = $pth['folder']['flags'] . $language . '.gif';
$label = is_readable($fn)
? tag('img src="' . $fn . '" alt="' . $language . '"')
: "[$language]";
$items []= '<a href="' . CMSIMPLE_ROOT . ($i > 0 ? "$language/" : '')
. '?autolang_force=' . $language . '">' . $label . '</a>';
}
return implode(' ', $items);
}
function Autolang()
{
global $sn, $sl;
if (isset($_GET['autolang_force'])) {
setcookie('autolang_choice', $_GET['autolang_force'], 0, CMSIMPLE_ROOT);
header("Location: $sn", true, 301);
exit();
}
$languages = Autolang_languages();
$userLang = user_language();
if (!$userLang) {
return;
}
if (!in_array($userLang, $languages)) {
$userLang = $languages[0];
}
if ($userLang != $sl) {
header("Location: $sn$userLang/", true, 303);
exit;
}
}
Autolang();
Could you please take another look and add it?
Thank you very much!
Re: Autodetect browser language & redirect
Ich habe den Code von Christoph für die userfuncs.php mal getestet, lokal unter Xampp mit PHP 8.2.12 und einem jungfräulichen XH 1.7.6.
Bei mir funktioniert es. Standardsprache en, Zusatzsprachen de, fr und it.
Rufe ich die Seite https://www.example.com/ auf und die Browsersprache ist de wird auf https://www.example.com/de weitergeleitet, dementsprechend auch bei den anderen Browsersprachen.
Bei mir funktioniert es. Standardsprache en, Zusatzsprachen de, fr und it.
Rufe ich die Seite https://www.example.com/ auf und die Browsersprache ist de wird auf https://www.example.com/de weitergeleitet, dementsprechend auch bei den anderen Browsersprachen.
„Bevor du den Pfeil der Wahrheit abschießt, tauche die Spitze in Honig!“ Ludwig's XH-Templates for MultiPage & OnePage
Re: Autodetect browser language & redirect
Danke fürs Testen, Ludwig,lck wrote: ↑Thu Sep 12, 2024 5:16 pmIch habe den Code von Christoph für die userfuncs.php mal getestet, lokal unter Xampp mit PHP 8.2.12 und einem jungfräulichen XH 1.7.6.
Bei mir funktioniert es. Standardsprache en, Zusatzsprachen de, fr und it.
Rufe ich die Seite https://www.example.com/ auf und die Browsersprache ist de wird auf https://www.example.com/de weitergeleitet, dementsprechend auch bei den anderen Browsersprachen.
habe es jetzt auf meiner kleinen Website online getestet, da dient wie auf der großen Website „at” als Standardsprache, damit ich „de” und „en” mit Sprachordner quasi als Zweitsprachen nutzen kann (wird Besuchern nicht als „at”/Österreich präsentiert, da es nur als Introseite (de|en) dient, von der zu /de/ oder /en/ gewechselt werden kann).
Sobald ich auf https://example.com/en/ wechseln möchte, erscheint vom Browser der Hinweis auf die Endlosschleife und in der Adresszeile steht hinter der Domain /en/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/ (ginge endlos weiter, aber Safari bemerkt die Endlosschleife und beendet das Trauerspiel mit der Fehlermeldung).
Inzwischen auch noch mit Googles Chrome getestet, hier von Root (Introseite https://example.com) gewechselt auf de:
Resultat: https://example.com/de/at/at/at/at/at/a ... /at/at/at/
Chrome bemerkt die Endlosschleife und beendet das Trauerspiel mit der Fehlermeldung.
In Chrome habe ich als einzige Browsersprache „Dänisch” hinterlegt, damit ich überhaupt die Introseite geladen bekomme, denn ansonsten wird entweder durch das PHP-Script aus userfuncs.php /de/ oder /en/ geladen.
Oder oder ein Apache-Script in der .htaccess-Datei erledigt das (fehlerfrei, aber ich wollte jetzt mal eine .htaccess-unabhängige Lösung probieren, daher meine Frage hier jetzt im Forum).
Mein Anliegen hier ist nicht dringend, aber für XH-Nutzer, die sich mit der .htaccess-Datei nicht auskennen, gar keinen Apache–Webserver nutzen oder einfach alles innerhalb von XH steuern wollen, ist eine solche Lösung sicher interessant.
Nachtrag: habe nochmal getestet und mir war noch eingefallen, dass ich ins Sprachordnerverzeichnis meiner Websites immer eine kleine .htaccess-Datei einfüge, um die sprachlich angepassten Fehlerseiten zu nutzen:
Code: Select all
DefaultLanguage de
ErrorDocument 403 /de/?403
ErrorDocument 404 /de/?404
ErrorDocument 410 /de/?410
Von Homepage (Standardsprache: Englisch) zu Deutsch: Umleitung auf example.com/de/en/ anstatt auf example.com/en/.
Und wenn Browsersprachen hinterlegt sind (Deutsch als Standard), dann lädt er nur example.com/de/ und Mausklick auf die englische Flagge (verlinkt mit root = EN) bewirkt … nichts.
Last edited by Michael_G on Sun Sep 15, 2024 9:20 pm, edited 2 times in total.
Re: Autodetect browser language & redirect
Nun weiß ich ja, das du in dieser Richtung sehr viel experimentierst.Michael_G wrote: ↑Thu Sep 12, 2024 8:35 pmSobald ich auf https://example.com/en/ wechseln möchte, erscheint vom Browser der Hinweis auf die Endlosschleife und in der Adresszeile steht hinter der Domain /en/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/de/ (ginge endlos weiter, aber Safari bemerkt die Endlosschleife und beendet das Trauerspiel mit der Fehlermeldung).
Bist du sicher, dass da nicht noch irgendwas anderes reinspielt?
Hast du mal mit einer wirklich sauberen Installation getestet?
Gruß Olaf, Plugins for CMSimple_XH
Ich habe schon lange den Verdacht, dass so viele so eifrig auf Gender, Trans und Queer machen:
Weil sie für das Fachliche ganz einfach zu doof sind.
Ich habe schon lange den Verdacht, dass so viele so eifrig auf Gender, Trans und Queer machen:
Weil sie für das Fachliche ganz einfach zu doof sind.
Re: Autodetect browser language & redirect
Ja, gleiches Ergebnis, wenn ich unverändertes XH v1.7.6 verwende.
Achte beim Testen mal darauf, keine (!) der Sprachen im Browser zu hinterlegen, welche Du verwendest.
Default-Sprache in XH, da nichts verändert: Englisch
Habe lediglich den 2lang-Ordner in „de” umbenannt, im content-Ordner einen Unterordner „de” angelegt und da hinein den content-Ordner aus 2lang verschoben (wie man das eben so macht, wenn man XH zweisprachig einrichtet/beginnt).
Nachtrag: habe nochmal getestet und mir war noch eingefallen, dass ich ins Sprachordnerverzeichnis meiner Websites immer eine kleine .htaccess-Datei einfüge, um die sprachlich angepassten Fehlerseiten zu nutzen (hier Beispiel für DE-Version):
– Das war der Grund für die Endlosschleife, denn eigentlich wird nach Anklicken der Flagge zum Sprachwechsel nicht korrekt umgeleitet:
Von Homepage (Standardsprache: Englisch) zu Deutsch: Umleitung auf example.com/de/en/ anstatt auf example.com/en/.
Homepage zeigt mit Default-Template oben rechts die deutsche Flagge.
Achte beim Testen mal darauf, keine (!) der Sprachen im Browser zu hinterlegen, welche Du verwendest.
Default-Sprache in XH, da nichts verändert: Englisch
Habe lediglich den 2lang-Ordner in „de” umbenannt, im content-Ordner einen Unterordner „de” angelegt und da hinein den content-Ordner aus 2lang verschoben (wie man das eben so macht, wenn man XH zweisprachig einrichtet/beginnt).
Nachtrag: habe nochmal getestet und mir war noch eingefallen, dass ich ins Sprachordnerverzeichnis meiner Websites immer eine kleine .htaccess-Datei einfüge, um die sprachlich angepassten Fehlerseiten zu nutzen (hier Beispiel für DE-Version):
Code: Select all
DefaultLanguage de
ErrorDocument 403 /de/?403
ErrorDocument 404 /de/?404
ErrorDocument 410 /de/?410
Von Homepage (Standardsprache: Englisch) zu Deutsch: Umleitung auf example.com/de/en/ anstatt auf example.com/en/.
Homepage zeigt mit Default-Template oben rechts die deutsche Flagge.
Last edited by Michael_G on Sun Sep 15, 2024 9:24 pm, edited 1 time in total.
Re: Autodetect browser language & redirect
Ich selber habe das gar nicht getestet.
Der Hinweis war nur so eine Idee, weil du ja oft in der Richtung unterwegs warst / bist.
Mal schauen, wenn ich Zeit, Lust und Laune habe.
Allerdings stehe ich dem autom. Weiterleiten eh sehr skeptisch gegenüber.
Gruß Olaf, Plugins for CMSimple_XH
Ich habe schon lange den Verdacht, dass so viele so eifrig auf Gender, Trans und Queer machen:
Weil sie für das Fachliche ganz einfach zu doof sind.
Ich habe schon lange den Verdacht, dass so viele so eifrig auf Gender, Trans und Queer machen:
Weil sie für das Fachliche ganz einfach zu doof sind.
Re: Autodetect browser language & redirect
Hallo Olaf, hallo Ludwig,
bei mir wird nur auf die „Zweitsprache”/Sprachordner /de/ bzw. /en/ weitergeleitet, wenn der Besucher bei sich die Browsersprache entsprechend hinterlegt hat.
Sonst empfängt meine Besucher die Introseite (root).
Ich dachte früher, dass Google selbst (weil Englisch) Seiten nur aus der englischsprachigen Perspektive prüft oder sich eher davon leiten lässt. Das ist aber nicht der Fall.
Googles Bots haben keine Browsersprache hinterlegt, werden nicht von sprachbedingten Weiterleitungen verwirrt und diese werden auch nicht bestraft – im Gegenteil! Wenn hreflang + canonical korrekt implementiert sind, freut das Google.
Bisher habe ich zur Spracherkennung diese .htaccess-Lösung implementiert, die hervorragend funktioniert:
Dieses Script stammt von einem Übersetzungsbüro, welches einen Artikel zu dem Thema veröffentlicht hatte.
Ich hatte das nur um die beiden Zeilen mit „RewriteCond %{QUERY_STRING} !…” ergänzt, damit ich als Admin weiterhin bei Bedarf auch die Introseite editieren kann (würde sonst immer auf Browsersprache umschalten).
Und am 11.08.2022 nur noch 403|404|410 hinzugefügt, damit Weiterleitungen von Fehlerseiten im root auf /de/ oder /en/ unterbunden werden (gäbe sonst nach z. B. ?404 noch eine WL auf /de/?404).
Ich habe meine Testversion gezippt und kann sie bei Interesse gern zur Verfügung stellen.
Dann kann das jeder selbst sehen, dass es eine unveränderte XH-Version aus dem XH-Repository ist.
Wie bereits erwähnt: für mich persönlich ist es nicht wichtig, ob die PHP-Version funktioniert oder nicht, aber da alle XH-Entwickler so darauf Wert legen, dass XH auch ganz ohne .htaccess-Lösungen alles kann und das für Anfänger auch sehr gut ist, hatte ich diese eben auch mal ausprobiert …
Für den Test habe ich auch keine .htaccess-Datei im Root verwendet.
bei mir wird nur auf die „Zweitsprache”/Sprachordner /de/ bzw. /en/ weitergeleitet, wenn der Besucher bei sich die Browsersprache entsprechend hinterlegt hat.
Sonst empfängt meine Besucher die Introseite (root).
Ich dachte früher, dass Google selbst (weil Englisch) Seiten nur aus der englischsprachigen Perspektive prüft oder sich eher davon leiten lässt. Das ist aber nicht der Fall.
Googles Bots haben keine Browsersprache hinterlegt, werden nicht von sprachbedingten Weiterleitungen verwirrt und diese werden auch nicht bestraft – im Gegenteil! Wenn hreflang + canonical korrekt implementiert sind, freut das Google.
Bisher habe ich zur Spracherkennung diese .htaccess-Lösung implementiert, die hervorragend funktioniert:
Code: Select all
#Browsersprache seit 28.03.2022 | perfekt: 11.08.2024
RewriteCond %{HTTP:Accept-Language} ^((?!en).)*de
RewriteCond %{QUERY_STRING} !(403|404|410|edit|file(browser)?|login|news(01|02|03)|normal|sysinfo) [NC]
RewriteRule ^$ de/ [R=301,L]
RewriteCond %{HTTP:Accept-Language} ^((?!de).)*en
RewriteCond %{QUERY_STRING} !(403|404|410|edit|file(browser)?|login|news(01|02|03)|normal|sysinfo) [NC]
RewriteRule ^$ en/ [R=301,L]
Ich hatte das nur um die beiden Zeilen mit „RewriteCond %{QUERY_STRING} !…” ergänzt, damit ich als Admin weiterhin bei Bedarf auch die Introseite editieren kann (würde sonst immer auf Browsersprache umschalten).
Und am 11.08.2022 nur noch 403|404|410 hinzugefügt, damit Weiterleitungen von Fehlerseiten im root auf /de/ oder /en/ unterbunden werden (gäbe sonst nach z. B. ?404 noch eine WL auf /de/?404).
Ich habe meine Testversion gezippt und kann sie bei Interesse gern zur Verfügung stellen.
Dann kann das jeder selbst sehen, dass es eine unveränderte XH-Version aus dem XH-Repository ist.
Wie bereits erwähnt: für mich persönlich ist es nicht wichtig, ob die PHP-Version funktioniert oder nicht, aber da alle XH-Entwickler so darauf Wert legen, dass XH auch ganz ohne .htaccess-Lösungen alles kann und das für Anfänger auch sehr gut ist, hatte ich diese eben auch mal ausprobiert …
Für den Test habe ich auch keine .htaccess-Datei im Root verwendet.