I setup Drupal 8 with 2 languages English & Arabic. Now when an article (English for eg.) does not have a translation (in Arabic) and the user switches the language from the menu. The page loads in Arabic and the article loads in English. I need to return a 404 or something different.

Any advise would be helpful.


It can not be done with core or contrib at them moment

To present 404 page not found (bad UX)

You could do something like this in your own module MODULENAME.module file

function MODULENAME_entity_view(array &$build, 
  \Drupal\Core\Entity\EntityInterface $entity, 
  \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

    $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
    $ent_lang = $entity->langcode->value;
    if($view_mode == "full" && $lang != $ent_lang){
      throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();

but once you go to the not found page the language switcher will not be able to take you back to the translated page though

To Hide untranslated languages in language switcher

There is a core issue about this and solutions are worked out but until it is solved you could create your own module

 * @file
 * Hide language switcher links for untranslated languages on an entity.
use Drupal\Core\Entity\ContentEntityInterface;

 * Implements hook_language_switch_links_alter().
function MODULENAME_language_switch_links_alter(array &$links, $type, $path) {
  if ($entity = MODULENAME_get_page_entity()) {
    $new_links = array();
    foreach ($links as $lang_code => $link) {
      try {
        if ($entity->getTranslation($lang_code)->access('view')) {
          $new_links[$lang_code] = $link;
      catch (\InvalidArgumentException $e) {
        // This language is untranslated so do not add it to the links.

    $links = $new_links;

    // If we're left with less than 2 links, then there's nothing to switch.
    // Hide the language switcher.
    if (count($links) < 2) {
      $links = array();

 * Retrieve the current page entity.
 * @return Drupal\Core\Entity\ContentEntityInterface
 *   The retrieved entity, or FALSE if none found.
function MODULENAME_get_page_entity() {
  $params = \Drupal::routeMatch()->getParameters()->all();
  $entity = reset($params);
  if ($entity instanceof ContentEntityInterface) {
    return $entity;
  return FALSE;

Above solution is taken from this post

To Hide untranslated menu items

You can use menu_multilingual which gives option when you create/edit a menu block to hide untraslated items.

  • Thank you @GiorgosK I've been banging my head against the issue for a whilst. I'll give it a shot. – alexseif Mar 14 '18 at 11:20
  • I'm going to keep working on it, but the first solution (which is the best so far) causes PHP Fatal error: Allowed memory size of 134217728 for different files. I'm debugging – alexseif Mar 14 '18 at 19:47
  • I have tested it and worked, not sure why it would need more memory. I suppose you have set your php memory to 128 which I would not recommend set it at least to 256MB (in your php.ini stackoverflow.com/questions/561066/…) – GiorgosK Mar 14 '18 at 20:20
  • So this is what I ended up with. ` $response = new RedirectResponse("/$lang"); drupal_set_message(t('Page not found.')); $response->send(); return; ` Still can't print that message though – alexseif Apr 25 '18 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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