New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Settings PLL_COOKIE has no effect when using static caching through routing #450
Comments
Hi @martin-braun, Just a side note from fellow static cache file user: I found out that Polylang works just fine without the cookie if you have I actually now have |
Hi @chesio, thank you for your reply. Since the time I created this issue, this is what I do, too, and it - as far as I could observe - really works. I thought when you go to the home page without a cookie it will redirect all the time to my primary language page that is not my homepage, but it does not. It either uses localStorage with JS redirection or session with PHP redirection. I will leave my issue open for the cases where Happy Sunday! |
Do you have |
@chesio Hi, I removed my last message to reply to this quote again. I was wrong, the first redirection was really broken due to WPFC. It seems whatever solution is implemented in Polylang, it's not working. So, I implemented some JavaScript that is limited to be used for languages without dialect specification, so "en", "de", "it", but not "en-GB" or "de-DE". Together with (function() {
if(location.pathname === '/') {
var lang = localStorage.getItem("lang");
var avaiLangs = ["en", "de"]; // configure me, first language is default
if(!lang) {
var prefLangs = navigator.languages || [ navigator.language || window.navigator.userLanguage ];
for(var i = 0; i < prefLangs.length; i++) {
var prefLang = prefLangs[i].split('-')[0];
for(var j = 0; j < avaiLangs.length; j++) {
if(prefLang === avaiLangs[j]) {
localStorage.setItem("lang", avaiLangs[j]);
if(j > 0) {
location.href = '/' + j ? avaiLangs[j] + '/' : '';
}
return;
}
}
}
localStorage.setItem("lang", avaiLangs[0]);
} else if(lang !== avaiLangs[0]) {
for(var i = 0; i < avaiLangs.length; i++) {
if(avaiLangs[i] === lang) {
location.href = '/' + lang + '/';
}
}
}
}
jQuery(document).ready(function( $ ) {
$(".nav .lang-item a").on("click", function() {
localStorage.setItem("lang", this.getAttribute("hreflang").split('-')[0]);
return true;
});
});
})(); This is designed to have the primary language on root ( This script needs to be implemented inline in the header of the website. I share this, so someone else in the future with the same problem can spare some time here doing the same. |
@martin-braun If your website runs on Apache then you might implement the redirects using I believe it's even possible to do so in case your default language has no If you're interested, I can post some examples. |
Hi @chesio, after deployment, my solution is not fast enough, because of the 2nd initial page load. I decided to disable "Hide URL language information for default language" in the Polylang settings, so it will always use the current language in the URL, like I inserted this into the
|
Hi @martin-braun, These rules are slightly more powerful: RewriteCond %{HTTP:Accept-Language} (en|de) [NC]
RewriteRule ^$ http://%{HTTP_HOST}/%1/ [L,R=302]
RewriteRule ^$ http://%{HTTP_HOST}/en/ [L,R=302] The first rule handles any user that has either EN or DE set as accepted language regardless of priority. For example an Italian user who speaks German as well will likely have Italian as most prefered language (ie. The second rule handles users that have neither EN nor DE set as accepted language and redirects them to EN version. Also, I would stick to 302 status code for redirect. Browser cache is not the only cache the HTTP request may encounter along its way (think of proxies etc.). 301 says permanent, which isn't true as the redirect depends on Accept-Language header. For that I also use this additional snippet: # Tell bots, that the content is based on language
<IfModule mod_headers.c>
Header append Vary Accept-Language
</IfModule> |
Hi @chesio, this is great. Thank you for taking your time to improve my solution. I wasn't thinking on cases where the English AND German language were missing in the Accept-Language header. So my solution would most likely not work as intended. You are also right about the permanent redirect. It makes sense and I will make use of it, definitely. Thank you! |
There have been too many topics on this feature included in Polylang having issues when there are 2 alternative approaches that work better & more reliably with caching (JS-based & .htaccess-based like this latest suggestion.) I somehow missed this one when I discussed this issue further at #294 (comment) (and also first mentioned in an older #236 (comment)). It seems strange that the option offered by Polylang is the least friendly when it comes to one of the major ways websites make their homepage & other pages load as quickly as possible when there are 2 other ways that wouldn't have that issue just to have it said addressing it is not possible (even with caching plugins adding support effectively making the page load slowly at least once [when it ideally should always be fast]) per the method being used now has an inherent limitation (hence why one or both of these other approaches should be offered) while then just providing custom code to be manually implemented on people's sites rather than implementing it officially a-la the limited PHP-based option provided now (definitely not ideal.) |
Thanks @chesio However, there is one problem. "Hide URL language information for default language" option is active. No grammar is added to the URL when the default language code is active. However, a second language is also added. (For example, such as /de/, /it/, /fr/). How can I update the above code in this case.? Thank you. |
Hi @esginmurat, short answer - you have to use self-referer check, see my answer here #450 (comment). Long answer: That's a quite tricky setup and to be honest I always do my best to discourage my clients and colleagues from setting up our multi-language projects this way. I would recommend you to do the same ;-) The main problem is that when someone visits the root URL - let's say
You may already see the problem: what if someone has browser configured to prefer one of the secondary languages on your website (= gets redirected due to 1.), but he actually wants to read your website in its main language (= should stay on home page due to 2.)? An example:
Now when Fritz visits One way how to solve this problem is... to set a cookie when user switches between languages and include the cookie in redirect decision making. That's why Polylang sets the The other way is to check whether the user comes to your root URL from outside world or your own website - the referrer check might help to distinguish these two cases. |
Prerequisites
master
branch of Polylang and the latest WordPress version.Introduction
This issue is a combination of the issues pll_language cookie and #248, which both got solved independently, but none of them work if you make use of all of this.
The website should have Polylang, GDPR Cookie Compliance and WP Fastest Cache installed.
The idea is to only write the polylang cookie when the user gives consent to the Strictly Necessary Cookies in the popup of the GDPR Cookie Compliance plugin. A quick simple way to do so is to put this simple one liner in wp-config.php:
However, this all breaks as soon as we bring WPFC into the game. WPFC is smart. It modifies the .htaccess to bypass the backend code, entirely. So afaik it serves static HTML/JS that was generated on the first load.
So this line will never be reached, so there is no chance to write the cookie after consent was given.
Possible solution
Modern cache solutions (including WPFC) are too smart, they bypass the backend PHP altogether from the second load on. This is brilliant to get the best loading performance out of it and should not cause any issues, as long as the content on the website is not dynamic.
Polylang should move its cookie set handling entirely to JS, in all cases. However, it should provide a JS api to prevent cookie creation. If the cookie set logic happens in jQuery's ready function and if it's checking for a specific flag in the window scope, I could disallow the cookie creation before.
Here is a basic example how this could look like:
This code would never be required to change, thus it would work, even when this all gets cached. It would not contain any conditional JS output.
The text was updated successfully, but these errors were encountered: