The Drupal 8 standard "Language switcher" dropdown does not give me what I need. What I need is to break everything apart into groups and subgroups, in a div, and have custom text for each Language, some of which are custom languages.

As ugly as my code is, I'm almost there, but I'm getting a node, instead of the actual page.

if I click on U.S. Spanish, I get: http://website.com/es-us/node/123 but I want: http://website.com/es-us/contactenos

if I click on U.S. English, I get http://website.com/en-us/node/123 but I want: http://website.com/en-us/contact-us

(note the difference in URL alias, by language)

I've found this page, and used it as my starting point: https://www.drupal.org/docs/8/multilingual/enable-language-negotiation

As I attempt to understand how I might do it, I have in my themename.theme:


* Implements hook_preprocess_page().
* @param $vars
function themename_preprocess_page(&$vars) {
 $current_path = \Drupal::service('path.current')->getPath();
// not used yet... 
$language = $vars['language']->getId();

  $fr_ca = '';
  $en_ca = '';
  $en_us = '';
  $es_us = '';
  $en_gb = '';

  $vars['en_us'] = '/en-us' . $current_path;
  $vars['es_us'] = '/es-us' . $current_path;
  $vars['en_ca'] = '/en-ca' . $current_path;
  $vars['fr_ca'] = '/fr-ca' . $current_path;
  $vars['en_gb'] = '/en-gb' . $current_path;

Then I was going to hardcode into the page.tpl.twig (for now, while I learn) something similar to:

<div class="region">
    <div class="country">
      <a class="lang-switcher" href="{{ en_us }}">English</a>
      <a class="lang-switcher" href="{{ es_us }}">Español</a>
     <div class="country">
      <a class="lang-switcher" href="{{ en_ca }}">English</a>
      <a class="lang-switcher" href="{{ fr_ca }}">Francais</a>

<div class="region">
  <div class="country">
    <!-- ETCETERA -->

I'm sure there are better ways to do this for a more experienced coder. But for now, I'm hoping I can get the alias in there.

I can't use "$current_uri = \Drupal::request()->getRequestUri();"

Because that is different for each page... For example, "contactenos" in Spanish versus "contact-us" in English


1 Answer 1


Seems you can do what you want with Url options and a language object like following.

// Get all activated languages.
$languages = \Drupal::languageManager()->getLanguages();

foreach ($languages as $language) {

  // Get the current URL in each language.
  $url = \Drupal\Core\Url::fromRoute('<current>')
    ->setOption('language', $language)->toString();

  // And add it to a custom array.
  $variables['my_langswitch'][$language->getId()] = $url;

But as I already said in the comments to your question, this should actually be put in a custom block. And since it's all just about a little bit of changing markup I'd even go for JavaScript here and stick to the built-in language switcher. Also as I'm not sure how above works with caching enabled.

If you prefer getting the paths one-by-one, get a language object first and then use that to get the path alias.

// Get Swedish language
if ($sv_language = \Drupal::languageManager()->getLanguage('sv')) {

  // Get Swedish URL.
  $sv_url = \Drupal\Core\Url::fromRoute('<current>')
    ->setOption('language', $sv_language)->toString();

  // Add it as custom variable.
  $variables['sv_url'] = $sv_url;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.