In short. Drupal copies the current request query array onto each generated native-language switch link.
Definition: Yes. Drupal's URL language negotiation implementation reads the current request's query string and attaches the resulting query array to every generated native-language switch link. The values therefore travel with those links through Drupal's URL option handling.
Key facts
- Drupal's
LanguageNegotiationUrlimplementation parses the request query string into a$queryarray before it creates language switch links, as shown in the Drupal 11.x source. - The same method assigns that array to the
queryentry of each link definition while iterating over Drupal's native languages. - Drupal's core
Urlclass defines thequeryURL option as an array of query key/value pairs to append to the URL, without URL encoding supplied in the option. - Symfony's Request class normalizes the request query string by alphabetizing key/value pairs and applying consistent escaping.
- PHP's
parse_strmanual says that the function parses a string as a URL query string and places the keys in the result array; values in that array are URL-decoded.
How does Drupal copy the query values?
The relevant method is getLanguageSwitchLinks(). It receives the current Symfony request and a Drupal Url object, initializes an empty array, and parses getQueryString() into it. It then loops over getNativeLanguages() and gives every link the same query array.
The core source shows the operation directly:
$links = [];
$query = [];
parse_str($request->getQueryString() ?? '', $query);
foreach ($this->languageManager->getNativeLanguages() as $language) {
$links[$language->getId()] = [
'url' => clone $url,
'title' => $language->getName(),
'language' => $language,
'attributes' => ['class' => ['language-link']],
'query' => $query,
];
}
This means the query values are attached to the generated link definitions, rather than being selected separately for each target language. The method clones the supplied URL for each link, while the query array is shared as the value of each link's query entry.
What form do the values take?
Symfony's request component normalizes the query string and documents alphabetized key/value pairs with consistent escaping. Drupal converts that string with PHP's parse_str, using the second argument so the result is written into $query.
PHP documents parse_str as parsing a string as if it were the query string passed through a URL. The manual also states that the values placed in the result array have already been URL-decoded using the rules of urldecode(). Drupal's URL API then expects the query option to contain key/value pairs without URL encoding before they are appended to the URL.
The conversion follows PHP's handling of repeated names. The PHP manual notes that repeated scalar fields with the same name are overwritten by the later value, while bracketed names such as foo[] produce an array. A site that relies on repeated query values should therefore inspect the actual array produced by parse_str when checking a language switch link.
What should a site owner check?
Inspect a page whose current request has a known query string, then inspect the generated language switch links. In the core path, the link definitions contain a query value populated from the request before the links are rendered. Compare the resulting target URLs with the source request, including decoded values and any repeated-name behavior.
The core implementation covers the query array it creates in getLanguageSwitchLinks(). It does not document how a custom language-switcher implementation, theme preprocessing, or later link alteration might replace that array; those changes need a separate code review.
Related terms
FAQ
Are query parameters copied to every language link?
Yes. The Drupal method builds one $query array from the request and assigns it to each link created while iterating over the native languages.
What happens when the request has no query string?
Drupal's null coalescing expression passes an empty string to parse_str when getQueryString() returns null, leaving the query array empty.
Are repeated query parameter names preserved as multiple scalar values?
PHP's manual says repeated scalar fields with the same name are overwritten by the later value. Bracketed field names use PHP's array syntax and can produce an array instead.
Sources
- Drupal, "LanguageNegotiationUrl.php", undated
- Drupal, "Url.php", undated
- Symfony, "Request.php", undated
- PHP, "parse_str", undated
Check how a page reads to answer engines. Open the GEO score analyzer