qTranslate-X redirects browser to a Canonical URL for the language detected before processing a request, which is done to improve consistency and compatibility with other plugins.
Canonical URL is defined by options
- Default Language
- Detect Browser Preferred Language
- URL Modification Mode
- Hide URL language information for default language
Note that option “Hide Untranslated Content”, as well as “Show displayed language prefix when content is not available for the selected language”, do not affect Canonical URL, which has been a confusion point for some admins.
When a user comes to the site for the very first time from an external link, or by typing url in, then language is set to the one encoded in the URL used. If URL does not have language information encoded in it, then it is determined by browser settings, and a redirect to a canonical URL may happen at that time. Once language is negotiated, a language cookie “qtrans_front_language” is set. The language negotiated will be kept as such during all subsequent browsing.
The language is only switched, if a URL has new language encoded in it with one of the methods available like ‘query’, ‘pre-path’, ‘pre-domain’, ‘per-domain’ (and soon to be added ‘slug’).
Except language switching menu and widgets, all internal links on a page usually encode the active language, unless a link was created by the theme or plugin without passing it through an appropriate filter. Language cookie help to keep the same language then.
If url does not have language information, then language is determined by the following steps:
- referrer url (if cookie is not set)
- cookie (‘qtrans_front_language’)
- browser setting (if main home page ‘/’)
- default language (as set on Settings/Languages configuration page)
and cookie is set with the result to be kept on further browsing until user explicitly switches the language through a menu or a widget, or with another url with language encoded.
If cookies are turned off in a browser, then language gets determined from a url, or from referrer url.
When option “Hide URL language information for default language” is on, Canonical URL for default language does not have language encoded. Then language will be negotiated as the default one, except when cookie is already set or referrer has different language encoded, to preserve consistency during the browsing. If referrer or cookie specify non-default language, then a redirect to Canonical URL for that language will also occur.
The nature of common confusion, which inspired this article to appear, is due to the dual ambiguity of a URL without language encoded, when option “Hide URL language information for default language” is on. On one hand, one may expect the URL without a language to be always resolved to the default language. On other hand, other users expect to preserve the active language during browsing, even if a URL without language encoded is used. The above is a description of how this ambiguity gets resolved.
Having cookie ‘qtrans_front_language’ also helps on AJAX calls, which almost never have language encoded in url. If option ‘Hide URL language information for default language’ is on, then there is no way to detect active language correctly on AJAX call, unless cookie is enabled.
If cookies are disabled in browser settings, then the language detection on bare urls is done based on referrer link, which replaces cookies functionality in most of the cases, including AJAX calls. Without cookies returning users might lose their language previously chosen, but once the language is chosen again, they should be fine.
On admin side, the cookie are always expected to be enabled, as WordPress require, and the current admin language is determined by ‘qtrans_admin_language’ cookie or the default language on the first visit. No redirections occur on admin side. The currently active Language Button is determined by ‘qtrans_edit_language’ cookie.
Further reading of the original discussion at GitHub may help to those who wish to dig deeper.