We have a site with multiple languages and have been using the Language Switch Dropdown menu to allow users to change languages on the site. But when we add "Browser | Language from the browser's language settings." as an additional detection option along with "Selected Language" then the selected language no longer works as it is always overridden by the browser's language, even if "Selected Language" is placed before it.
The ideal workflow would be:
- Language is detected from the browser and translated
- The Language Dropdown shows the current language (currently it always displays the default language, even if the browser detects and switches to a different language)
- The user can then override the browser language by selecting a different language from the drop-down switcher. (Currently the dropdown has no effect if a language is detected via the browser)
SOLUTION EDIT:
The proposed solution did not work for us so we ended up writing a custom form alter function and using a one-time cookie to achieve the functionality we were looking for.
In the language detection, we have "selected language" enable as the first item then "URL" and the second item and no other detections are used.
Then we used the below hook to the detect and set the language from the browser one-time using a cookie. The hook also sets the default value of the language dropdown so it shows what the language is, even if set from the browser.
<?php
function MY_MODULE_form_lang_dropdown_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
// Only run if our custom language cookie is not set yet
if (!isset($_COOKIE['Drupal_visitor_user_lang'])){
// Get language set in browser
$language = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
user_cookie_save(['user_lang' => $language]);
// Set the language dropdown's default value
$form['lang_dropdown_select']['#default_value'] = $language;
$current_path = \Drupal::service('path.current')->getPath();
$path = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
$config = \Drupal::config('system.site');
$front_uri = $config->get('page.front');
$front_alias = \Drupal::service('path.alias_manager')->getAliasByPath($front_uri);
if ($path == $front_alias){
$path = '';
}
$default_language = \Drupal::languageManager()->getDefaultLanguage()->getId();
if ($language == $default_language){
$language = '';
}
$response = new RedirectResponse('/' . $language . $path);
$response->send();
}
$language = \Drupal::languageManager()->getCurrentLanguage()->getId();
$form['lang_dropdown_select']['#default_value'] = $language;
}