qtranslate / qtranslate-xt

qTranslate-XT (eXTended) - reviving qTranslate-X multilingual plugin for WordPress. A new community-driven plugin soon. Built-in modules for WooCommerce, ACF, slugs and others.
GNU General Public License v2.0
558 stars 107 forks source link

[module: slugs] "Detect Browser Language" feature redirects to 404 when using Slugs module #1328

Open estebanlopeza opened 1 year ago

estebanlopeza commented 1 year ago

The "Detect Browser Language" feature redirects to 404 when posts or pages use language specific slugs using "Slugs translation" module. This happens when you try to access a post using the slug for the main language (Eg: English) using a browser that uses a secondary language (Eg: Spanish)

Steps to reproduce the behavior: Suppousing the plugin is configured in English (as main language) and Spanish

  1. Enable "Slugs translation" module (Settings > Integrations)
  2. Check the "Detect Browser Language" option (Settings > General)
  3. Create and publish a post with two different slugs for EN (Eg: https://your-site.com/the-slug) and ES (https://your-site.com/es/el-slug).
  4. Using an incognito browser configured in Spanish, try to access the post using the main language url (https://your-site.com/the-slug). It throws a 404 error.

Expected behavior It should redirect to the Spanish version of the post.

Debug info Versions { "PHP_VERSION": "8.0.7", "WP_VERSION": "6.2", "QTX_VERSION": "3.15.0.dev.0", "Plugins": [ "All in One SEO 4.3.5.1", "Asesor de Cookies RGPD 0.32", "Better Search Replace 1.4.2", "Contact Form 7 5.7.5.1", "Easy Table of Contents 2.0.47.1", "Imagify 2.1.1", "WPBakery Page Builder 6.10.0", "Loco Translate 2.6.4", "OG — Better Share on Social Media 3.2.1", "qTranslate-XT 3.14.1", "Woodmart Core 1.0.35", "WP Rocket 3.12.5.1" ] }

Configuration { "default_language": "en", "enabled_languages": [ "es", "en", "pb" ], "locale": { "es": "es_ES", "en": "en_US", "pb": "pt_BR" }, "date_format": { "es": "%d \d\e %B \d\e %Y", "en": "%A %B %e%q, %Y", "pb": "%d \d\e %B \d\e %Y" }, "time_format": { "es": "%H:%M hrs.", "en": "%I:%M %p", "pb": "%H:%M hrs." }, "url_mode": 2, "use_strftime": 3, "filter_options_mode": 0, "language_name_case": 0, "detect_browser_language": true, "hide_untranslated": true, "show_menu_alternative_language": false, "show_displayed_language_prefix": false, "show_alternative_content": false, "hide_default_language": true, "use_secure_cookie": false, "header_css_on": true, "text_field_filters": [], "disable_client_cookies": false, "url_info": { "cookie_lang_front": "en", "cookie_lang_admin": "en", "cookie_front_or_admin_found": true, "pagenow": "admin-ajax.php", "REQUEST_METHOD": "GET", "WP_ADMIN": true, "DOING_AJAX_POST": [], "scheme": "https", "host": "interlabd.com", "path": "/wp-admin/admin-ajax.php", "query": "action=admin_debug_info", "path-base": "", "wp-path": "/wp-admin/admin-ajax.php", "language_neutral_path": true, "http_referer": "https://interlabd.com/wp-admin/options-general.php?page=qtranslate-xt", "referer_admin": true, "doing_front_end": false, "lang_cookie_admin": "en", "lang_admin": "en", "language": "en", "set_cookie": false, "page_referer": "options-general.php" }, "language": "en", "editor_mode": 0, "highlight_mode": 1, "auto_update_mo": true, "hide_lsb_copy_content": false, "lsb_style": "simple-buttons.css", "config_files": [ "./i18n-config.json" ], "custom_fields": [], "custom_field_classes": [], "post_type_excluded": [], "admin_enabled_modules": { "all-in-one-seo-pack": true, "slugs": true, "acf": false, "events-made-easy": false, "jetpack": false, "google-site-kit": false, "gravity-forms": false, "woo-commerce": false, "wp-seo": false }, "qtrans_compatibility": false }

herrvigg commented 1 year ago

I'm not sure how to interpret this, but I believe the browser language and incognito mode don't matter much. It's probably the language cookie that prevails before the browser language. Being in incognito mode does not deactivate the cookies, they remain for the session until you go out of that mode (but they are not visible outside) You can find it under the name qtrans_front_language from Application / Storage.

So, if you are in Spanish, the cookie says to remain in Spanish. It doesn't find that slug in Spanish so it gives a 404. If you browse to an English URL (not in the browser language) for example by enforcing it to /en/ that will save en language in the cookie. Then if you ask for the english slug it will find it.

@spleen1981 How is Slugs supposed to work, should it switch language if it finds the same URL with a different slug in another language?

spleen1981 commented 1 year ago

I don't think the detect browser language feature and slugs module should be used at the same time. The first is though to be used with constant slugs, searching the same in the browser detected language (e.g. lang1/slug, lang2/slug etc.). So if I have lang1/slug1 and lang2/slug2 the detect language feature may end up with lang1/slug2 or lang2/slug1 which may not work. I guess this feature would work good only for the home page and for the pages with same slug for all languages. There is no language detection based on the requested slug to override browser detected language currently. Maybe we should just automatically disable the 'detect browser language' feature if slugs module is enabled.

herrvigg commented 1 year ago

@estebanlopeza does that work if you disabled the browser language detection?

@spleen1981 I'm not sure it's enough to disable the browser detection. What happens if the "wrong" language is set in the cookie by other means? I don't know all the details about the slugs implementation, but what the OP is asking looks reasonable. IMO we should make a distinction between auto-detection and explicit language switching.

spleen1981 commented 1 year ago

We could use the qtranslate_language_detect_redirect filter from within the slugs module to pass false, that should cover all cases of language detection. Maybe we could preserve current behaviour only if site url is called, which could be the case user could benefit of a redirection as they are not looking for a specific content. Otherwise I'm not sure if user requesting slug1 (which is a slug specific to a single language) wants to be redirected to slug2 for any reason, as the request is very specific (while in case of single slugs it could be considered 'generic' from language point of view, then a redirection could make more sense).

spleen1981 commented 1 year ago

Possible implementation of the above here: 171e2be4278e0cdccb26602404f7b6d568d49ae0, it should fix OP issue

spleen1981 commented 1 year ago

@estebanlopeza can you test fix_language_detect_slugs branch?

chrilleferna commented 8 months ago

I'm having a similar problem to the one reported here, using the version 3.15.2 of the plugin

The reason this is important is that crawlers (Google etc.) are running into problems

My site is in English and French, with French as the default language and the settings set to hide the URL language information for the default language. I have deselected browser language detection.

Let's assume I create a page with slug "test", set the French slug to "mon-test" and the English slug to "my-test".

This page can now be accessed as

../fr/mon-test/ and ../en/my-test/

It can ONLY be accessed with ../mon-test/ if the site is set to French. That means that

../fr/mon-test/ followed by ../mon-test/ works, but

../en/my-test/ followed by ../mon-test/ breaks with 404 since it redirects to ../en/mon-test/

This means that Google is not able to index the pages in the default language (using URL:s without the language marker) if it has accessed the English version first, which I can confirm is happening.

From the discussion above I'm not sure if this is resolved in a pull request which has not yet been merged into the master branch.

spleen1981 commented 8 months ago

Yes it should be fixed by #1364, you can test this branch to see if it solves your issue.

chrilleferna commented 8 months ago

@spleen1981 Thanks Giovanni Much better - almost perfect, but works fine if-and-only-if you do not check the "hide the language marker for the default language".

So, after unchecking this, URL:s with the language marker automatically switch to the language indicated in the URL and the page is correctly accessed, which is great.

URL:s without the language marker also redirects to the correct page for the default language, with a new URL containing the language marker.

It's a little bit funny that even if you don't check the "Hide URL Language Information for default language" this works.

I don't need to hide the language marker for the default langtuage, so for me this is sufficient, and I think and hope Google will be happy too.

spleen1981 commented 8 months ago

Much better - almost perfect, but works fine if-and-only-if you do not check the "hide the language marker for the default language".

What is exactly the issue when the default language is set as hidden? Same described above?

chrilleferna commented 8 months ago

When it is set to hidden there are still redirects to URL:s with the language marker for the default language. This happens when I paste an URL without language marker into the address bar. And also when using the language switcher, so for example if I'm on the page /en/my-test and hit the language switcher I'm directed to the page /fr/mon-test, which results in error 404, since there now is a language marker in the URL. And if I now hit the language switcher again I'm directed to /en/mon-test => error 404, since it should be /en/my-test

Then an auxiliary question: will this branch be merged into the master branch so that I can count on it for later updates?

herrvigg commented 8 months ago

Then an auxiliary question: will this branch be merged into the master branch so that I can count on it for later updates?

I've been crazy busy these last months. I'll try to sync this week at least on this topic.

spleen1981 commented 8 months ago

Hi @chrilleferna, I made some modifications, can you test again the same branch to check if it's working with AND without "hide the language marker for the default language" activated?

chrilleferna commented 8 months ago

Hi @spleen1981 YES!! Thanks. This seems to work fine! And hi @herrvigg many thanks to you for your devotion to keep Qtranslate-XT going. It would be great if you can sync with the latest version of this branch so that future updates will work with the slug module