Browser language detection is skipped, if a browser/robot without Accept-Language header calls the page and the default language node is put into cache. Afterwards, the default language node is always delivered until cache is cleared/rebuilt, the browser language of subsequent requests is ignored.
My language detection order is:
- URL
- Browser
- Default / selected language
I built a test to illustrate this issue (drupal-browser-detection-test-2986325-1-D8.patch).
My solution for this issue is to trigger page_cache_kill_switch even if no Accept-Language header is set (but $this->languageManager and $request are not NULL). That is in the middle between the old code and the current.
LanguageNegotiationBrowser.php:
if ($this->languageManager && $request) {
if ($request->server->get('HTTP_ACCEPT_LANGUAGE')) {
$http_accept_language = $request->server->get('HTTP_ACCEPT_LANGUAGE');
$langcodes = array_keys($this->languageManager->getLanguages());
$mappings = $this->config->get('language.mappings')->get('map');
$langcode = UserAgent::getBestMatchingLangcode($http_accept_language, $langcodes, $mappings);
}
// Internal page cache with multiple languages and browser negotiation
// could lead to wrong cached sites. Therefore disabling the internal
// page cache.
// @todo Solve more elegantly in https://www.drupal.org/node/2430335.
\Drupal::service('page_cache_kill_switch')->trigger();
}