diff --git a/core/core.services.yml b/core/core.services.yml
index acd765e78f..e06dc860f9 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -762,6 +762,10 @@ services:
     class: Drupal\Core\Menu\DefaultMenuLinkTreeManipulators
     arguments: ['@access_manager', '@current_user', '@entity_type.manager', '@module_handler']
   Drupal\Core\Menu\DefaultMenuLinkTreeManipulators: '@menu.default_tree_manipulators'
+  menu.language_tree_manipulator:
+    class: Drupal\Core\Menu\LanguageMenuLinkManipulator
+    arguments: ['@language_manager']
+  Drupal\Core\Menu\LanguageMenuLinkManipulator: '@menu.language_tree_manipulator'
   menu.active_trail:
     class: Drupal\Core\Menu\MenuActiveTrail
     arguments: ['@plugin.manager.menu.link', '@current_route_match', '@cache.menu', '@lock']
diff --git a/core/lib/Drupal/Core/Menu/LanguageMenuLinkManipulator.php b/core/lib/Drupal/Core/Menu/LanguageMenuLinkManipulator.php
new file mode 100644
index 0000000000..5ecb182b57
--- /dev/null
+++ b/core/lib/Drupal/Core/Menu/LanguageMenuLinkManipulator.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Core\Menu;
+
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\Core\Language\LanguageInterface;
+
+/**
+ * Provides a menu link language manipulator.
+ */
+class LanguageMenuLinkManipulator {
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * LanguageMenuLinkManipulator constructor.
+   *
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   *   The language manager.
+   */
+  public function __construct(LanguageManagerInterface $language_manager) {
+    $this->languageManager = $language_manager;
+  }
+
+  /**
+   * Hide menu links that do not have translation for the current language.
+   *
+   * @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
+   *   The menu link tree to manipulate.
+   *
+   * @return \Drupal\Core\Menu\MenuLinkTreeElement[]
+   *   The manipulated menu link tree.
+   */
+  public function filterLanguage(array $tree) : array {
+    $current_language = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
+
+    foreach ($tree as $key => $link) {
+      if ($link->link instanceof MenuLinkTranslationInterface) {
+        // If the link is translatable, but has no translation, hide it.
+        if ($link->link->isTranslatable() && !$link->link->hasTranslation($current_language)) {
+          unset($tree[$key]);
+        }
+        elseif ($link->hasChildren) {
+          // Recursively call this method to filter out untranslated children.
+          $tree[$key]->subtree = $this->filterLanguage($link->subtree);
+        }
+      }
+    }
+    return $tree;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTranslationInterface.php b/core/lib/Drupal/Core/Menu/MenuLinkTranslationInterface.php
new file mode 100644
index 0000000000..3153243e9d
--- /dev/null
+++ b/core/lib/Drupal/Core/Menu/MenuLinkTranslationInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\Core\Menu;
+
+/**
+ * Defines an interface for exposing multilingual capabilities.
+ */
+interface MenuLinkTranslationInterface {
+
+  /**
+   * Determines if menu link has a translation.
+   *
+   * @param string $langcode
+   *   The langcode.
+   *
+   * @return bool
+   *   TRUE if menu link has a translation, FALSE if not.
+   */
+  public function hasTranslation($langcode) : bool;
+
+}
diff --git a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php
index 1b8b141afb..32ddebec38 100644
--- a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php
+++ b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php
@@ -7,13 +7,14 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Menu\MenuLinkBase;
+use Drupal\Core\Menu\MenuLinkTranslationInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides the menu link plugin for content menu links.
  */
-class MenuLinkContent extends MenuLinkBase implements ContainerFactoryPluginInterface {
+class MenuLinkContent extends MenuLinkBase implements ContainerFactoryPluginInterface, MenuLinkTranslationInterface {
 
   /**
    * Entities IDs to load.
@@ -279,6 +280,13 @@ public function isTranslatable() {
     return $this->getEntity()->isTranslatable();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function hasTranslation($langcode) : bool {
+    return $this->getEntity()->hasTranslation($langcode);
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
index 463b6800b8..297fa987dd 100644
--- a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
@@ -189,6 +189,7 @@ public function build() {
     $manipulators = [
       ['callable' => 'menu.default_tree_manipulators:checkAccess'],
       ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
+      ['callable' => 'menu.language_tree_manipulator:filterLanguage'],
     ];
     $tree = $this->menuTree->transform($tree, $manipulators);
     return $this->menuTree->build($tree);
diff --git a/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTranslationTest.php b/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTranslationTest.php
new file mode 100644
index 0000000000..22762311b2
--- /dev/null
+++ b/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTranslationTest.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace Drupal\Tests\system\Kernel\Block;
+
+use Drupal\Core\Language\Language;
+use Drupal\system\Entity\Menu;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\menu_link_content\Entity\MenuLinkContent;
+
+/**
+ * Tests \Drupal\system\Plugin\Block\SystemMenuBlock translation.
+ *
+ * @group Block
+ *
+ * @see \Drupal\system\Plugin\Block\SystemMenuBlock
+ */
+class SystemMenuBlockTranslationTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'block',
+    'content_translation',
+    'language',
+    'link',
+    'menu_link_content',
+    'system',
+    'user',
+  ];
+
+  /**
+   * The menu for testing.
+   *
+   * @var \Drupal\system\MenuInterface
+   */
+  protected $menu;
+
+  /**
+   * The block manager service.
+   *
+   * @var \Drupal\Core\block\BlockManagerInterface
+   */
+  protected $blockManager;
+
+  /**
+   * The content translation manager.
+   *
+   * @var \Drupal\content_translation\ContentTranslationManagerInterface|\Drupal\content_translation\BundleTranslationSettingsInterface
+   */
+  protected $contentTranslationManager;
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManager
+   */
+  protected $languageManager;
+
+  /**
+   * The default language.
+   *
+   * @var \Drupal\Core\Language\LanguageDefault
+   */
+  protected $languageDefault;
+
+  /**
+   * French language.
+   *
+   * @var \Drupal\Core\Language\LanguageInterface
+   */
+  protected $language;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    // Install schemas & config.
+    $this->installConfig(['language']);
+    $this->installEntitySchema('configurable_language');
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('menu_link_content');
+
+    // Get services.
+    $this->blockManager = $this->container->get('plugin.manager.block');
+    $this->contentTranslationManager = $this->container->get('content_translation.manager');
+    $this->languageManager = $this->container->get('language_manager');
+    $this->languageDefault = $this->container->get('language.default');
+
+    // Add custom menu.
+    $this->menu = Menu::create([
+      'id' => 'mock',
+      'label' => $this->randomMachineName(16),
+      'description' => 'Description text',
+    ]);
+    $this->menu->save();
+
+    // Add French language and make menu links translatable.
+    $this->language = ConfigurableLanguage::createFromLangcode('fr');
+    $this->language->save();
+    $this->contentTranslationManager->setEnabled('menu_link_content', 'menu_link_content', TRUE);
+  }
+
+  /**
+   * Tests that menu blocks display links in proper language.
+   */
+  public function testMenuBlockTranslation() {
+    // Create menu links in each language.
+    $languages = [
+      'en' => 'English',
+      'fr' => 'French',
+      Language::LANGCODE_NOT_SPECIFIED => 'Not specified',
+      Language::LANGCODE_NOT_APPLICABLE => 'Not applicable',
+    ];
+    $links = [];
+    foreach ($languages as $langcode => $langname) {
+      $link = MenuLinkContent::create([
+        'title' => "test $langname",
+        'link' => ['uri' => 'https://www.drupal.org/'],
+        'menu_name' => $this->menu->id(),
+        'external' => TRUE,
+        'bundle' => 'menu_link_content',
+        'langcode' => $langcode,
+      ]);
+      $link->save();
+      $links[$langcode] = $link;
+    }
+
+    // Place menu block in a region.
+    /** @var \Drupal\Core\Block\BlockPluginInterface */
+    $block = $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), [
+      'region' => 'footer',
+      'id' => 'menu_block_footer',
+      'theme' => 'stark',
+      'level' => 1,
+      'depth' => 0,
+    ]);
+
+    // Viewing block from English interface should show links which language is
+    // - English
+    // - Not specified
+    // - Not applicable
+    // It should not show French links.
+    $build = $block->build();
+    $items = $build['#items'] ?? [];
+    $this->assertArrayHasKey('menu_link_content:' . $links['en']->uuid(), $items);
+    $this->assertArrayNotHasKey('menu_link_content:' . $links['fr']->uuid(), $items);
+    $this->assertArrayHasKey('menu_link_content:' . $links[Language::LANGCODE_NOT_SPECIFIED]->uuid(), $items);
+    $this->assertArrayHasKey('menu_link_content:' . $links[Language::LANGCODE_NOT_APPLICABLE]->uuid(), $items);
+
+    // Viewing block from French interface should show links which language is
+    // - French
+    // - Not specified
+    // - Not applicable
+    // It should not show English links.
+    $this->languageDefault->set($this->language);
+    $this->languageManager->reset();
+    $build = $block->build();
+    $items = $build['#items'] ?? [];
+    $this->assertArrayNotHasKey('menu_link_content:' . $links['en']->uuid(), $items);
+    $this->assertArrayHasKey('menu_link_content:' . $links['fr']->uuid(), $items);
+    $this->assertArrayHasKey('menu_link_content:' . $links[Language::LANGCODE_NOT_SPECIFIED]->uuid(), $items);
+    $this->assertArrayHasKey('menu_link_content:' . $links[Language::LANGCODE_NOT_APPLICABLE]->uuid(), $items);
+  }
+
+}
