diff --git a/core/modules/aggregator/config/install/views.view.aggregator_sources.yml b/core/modules/aggregator/config/install/views.view.aggregator_sources.yml
index 8612cff..3e904ff 100644
--- a/core/modules/aggregator/config/install/views.view.aggregator_sources.yml
+++ b/core/modules/aggregator/config/install/views.view.aggregator_sources.yml
@@ -18,14 +18,17 @@ display:
     id: default
     display_title: Master
     position: 0
+    provider: views
     display_options:
       access:
         type: perm
         options:
           perm: 'access news feeds'
+        provider: null
       cache:
         type: none
         options: {  }
+        provider: views
       query:
         type: views_query
         options:
@@ -34,6 +37,7 @@ display:
           replica: false
           query_comment: false
           query_tags: {  }
+        provider: views
       exposed_form:
         type: basic
         options:
@@ -44,6 +48,7 @@ display:
           expose_sort_order: true
           sort_asc_label: Asc
           sort_desc_label: Desc
+        provider: views
       pager:
         type: full
         options:
@@ -78,9 +83,11 @@ display:
           field: fid
           id: fid
           plugin_id: numeric
+          provider: views
           relationship: none
           group_type: group
           admin_label: ''
+          dependencies: {  }
           label: ''
           exclude: false
           alter:
@@ -131,8 +138,6 @@ display:
           format_plural_plural: '@count'
           prefix: ''
           suffix: ''
-          entity_type: aggregator_feed
-          entity_field: fid
       filters: {  }
       sorts: {  }
       title: Sources
@@ -143,11 +148,13 @@ display:
       arguments: {  }
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
   feed_1:
     display_plugin: feed
     id: feed_1
     display_title: Feed
     position: 2
+    provider: views
     display_options:
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
@@ -155,6 +162,7 @@ display:
         type: opml
         options:
           grouping: {  }
+        provider: views
       path: aggregator/opml
       fields:
         title:
@@ -164,6 +172,9 @@ display:
           relationship: none
           group_type: group
           admin_label: ''
+          dependencies:
+            module:
+              - aggregator
           label: ''
           exclude: false
           alter:
@@ -207,8 +218,7 @@ display:
           hide_alter_empty: true
           display_as_link: false
           plugin_id: aggregator_title_link
-          entity_type: aggregator_feed
-          entity_field: title
+          provider: aggregator
         url:
           id: url
           table: aggregator_feed
@@ -216,6 +226,9 @@ display:
           relationship: none
           group_type: group
           admin_label: ''
+          dependencies:
+            module:
+              - views
           label: ''
           exclude: false
           alter:
@@ -259,8 +272,7 @@ display:
           hide_alter_empty: true
           display_as_link: false
           plugin_id: url
-          entity_type: aggregator_feed
-          entity_field: url
+          provider: views
         description:
           id: description
           table: aggregator_feed
@@ -268,6 +280,9 @@ display:
           relationship: none
           group_type: group
           admin_label: ''
+          dependencies:
+            module:
+              - views
           label: ''
           exclude: false
           alter:
@@ -310,8 +325,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           plugin_id: xss
-          entity_type: aggregator_feed
-          entity_field: description
+          provider: views
         link:
           id: link
           table: aggregator_feed
@@ -319,6 +333,9 @@ display:
           relationship: none
           group_type: group
           admin_label: ''
+          dependencies:
+            module:
+              - views
           label: ''
           exclude: false
           alter:
@@ -362,8 +379,7 @@ display:
           hide_alter_empty: true
           display_as_link: false
           plugin_id: url
-          entity_type: aggregator_feed
-          entity_field: link
+          provider: views
       defaults:
         fields: false
         title: false
@@ -378,24 +394,32 @@ display:
           language_field: ''
           xml_url_field: url
           url_field: ''
+        provider: views
       displays:
         page_1: page_1
         default: '0'
       title: 'OPML feed'
       sitename_title: true
+      display_extenders: {  }
   page_1:
     display_plugin: page
     id: page_1
     display_title: Page
     position: 1
+    provider: views
     display_options:
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
       path: aggregator/sources
       menu:
-        type: normal
+        type:
+          normal: normal
+          tab: '0'
+          'default tab': '0'
         title: Sources
         description: ''
+        parent: ''
         weight: 0
         context: '0'
         menu_name: tools
+      display_extenders: {  }
diff --git a/core/modules/file/config/install/views.view.files.yml b/core/modules/file/config/install/views.view.files.yml
index 711efee..2176965 100644
--- a/core/modules/file/config/install/views.view.files.yml
+++ b/core/modules/file/config/install/views.view.files.yml
@@ -176,8 +176,6 @@ display:
           empty: ''
           hide_alter_empty: true
           plugin_id: file
-          entity_type: file
-          entity_field: fid
         filename:
           id: filename
           table: file_managed
@@ -210,8 +208,6 @@ display:
           empty: ''
           hide_alter_empty: true
           plugin_id: file
-          entity_type: file
-          entity_field: filename
         filemime:
           id: filemime
           table: file_managed
@@ -263,8 +259,6 @@ display:
           link_to_file: false
           filemime_image: false
           plugin_id: file_filemime
-          entity_type: file
-          entity_field: filemime
         filesize:
           id: filesize
           table: file_managed
@@ -315,8 +309,6 @@ display:
           hide_alter_empty: true
           file_size_display: formatted
           plugin_id: file_size
-          entity_type: file
-          entity_field: filesize
         status:
           id: status
           table: file_managed
@@ -366,8 +358,6 @@ display:
           empty_zero: false
           hide_alter_empty: true
           plugin_id: file_status
-          entity_type: file
-          entity_field: status
         created:
           id: created
           table: file_managed
@@ -420,8 +410,6 @@ display:
           custom_date_format: ''
           timezone: ''
           plugin_id: date
-          entity_type: file
-          entity_field: created
         changed:
           id: changed
           table: file_managed
@@ -474,8 +462,6 @@ display:
           custom_date_format: ''
           timezone: ''
           plugin_id: date
-          entity_type: file
-          entity_field: changed
         count:
           id: count
           table: file_usage
@@ -573,8 +559,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: string
-          entity_type: file
-          entity_field: filename
         filemime:
           id: filemime
           table: file_managed
@@ -613,8 +597,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: string
-          entity_type: file
-          entity_field: filemime
         status:
           id: status
           table: file_managed
@@ -654,8 +636,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: file_status
-          entity_type: file
-          entity_field: status
       sorts: {  }
       title: Files
       header: {  }
@@ -682,6 +662,7 @@ display:
       show_admin_links: true
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
   page_1:
     display_plugin: page
     id: page_1
@@ -690,12 +671,16 @@ display:
     display_options:
       path: admin/content/files
       menu:
-        type: tab
+        type:
+          tab: tab
+          normal: '0'
+          'default tab': '0'
         title: Files
         description: ''
-        menu_name: admin
+        parent: ''
         weight: 0
-        context: ''
+        context: '0'
+        menu_name: admin
       display_description: ''
       defaults:
         pager: true
@@ -711,6 +696,7 @@ display:
           required: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
   page_2:
     display_plugin: page
     id: page_2
@@ -999,8 +985,6 @@ display:
           break_phrase: false
           not: false
           plugin_id: file_fid
-          entity_type: file
-          entity_field: fid
       style:
         type: table
         options:
@@ -1062,3 +1046,4 @@ display:
           required: true
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
diff --git a/core/modules/node/config/install/views.view.content.yml b/core/modules/node/config/install/views.view.content.yml
index 2a44101..79d5e0b 100644
--- a/core/modules/node/config/install/views.view.content.yml
+++ b/core/modules/node/config/install/views.view.content.yml
@@ -1,3 +1,4 @@
+uuid: 3726fb5a-ed6c-4c0f-b20e-14f6108dd984
 langcode: en
 status: true
 dependencies:
@@ -148,7 +149,6 @@ display:
           empty_zero: false
           hide_alter_empty: true
           plugin_id: node_bulk_form
-          entity_type: node
         title:
           id: title
           table: node_field_data
@@ -165,8 +165,6 @@ display:
           hide_alter_empty: true
           link_to_node: true
           plugin_id: node
-          entity_type: node
-          entity_field: title
         type:
           id: type
           table: node_field_data
@@ -184,8 +182,6 @@ display:
           link_to_node: false
           machine_name: ''
           plugin_id: node_type
-          entity_type: node
-          entity_field: type
         name:
           id: name
           table: users_field_data
@@ -206,8 +202,6 @@ display:
           anonymous_text: ''
           format_username: true
           plugin_id: user_name
-          entity_type: user
-          entity_field: name
         status:
           id: status
           table: node_field_data
@@ -227,8 +221,6 @@ display:
           type_custom_false: ''
           not: ''
           plugin_id: boolean
-          entity_type: node
-          entity_field: status
         changed:
           id: changed
           table: node_field_data
@@ -247,8 +239,6 @@ display:
           custom_date_format: ''
           timezone: ''
           plugin_id: date
-          entity_type: node
-          entity_field: changed
         edit_node:
           id: edit_node
           table: node
@@ -257,7 +247,6 @@ display:
           exclude: true
           text: Edit
           plugin_id: node_link_edit
-          entity_type: node
         delete_node:
           id: delete_node
           table: node
@@ -266,7 +255,6 @@ display:
           exclude: true
           text: Delete
           plugin_id: node_link_delete
-          entity_type: node
         dropbutton:
           id: dropbutton
           table: views
@@ -286,7 +274,6 @@ display:
           value: false
           plugin_id: node_status
           group: 1
-          entity_type: node
         status:
           id: status
           table: node_field_data
@@ -331,8 +318,6 @@ display:
                 operator: '='
                 value: '0'
           plugin_id: boolean
-          entity_type: node
-          entity_field: status
         type:
           id: type
           table: node_field_data
@@ -372,8 +357,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: bundle
-          entity_type: node
-          entity_field: type
         title:
           id: title
           table: node_field_data
@@ -412,8 +395,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: string
-          entity_type: node
-          entity_field: title
         langcode:
           id: langcode
           table: node_field_data
@@ -453,8 +434,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: language
-          entity_type: node
-          entity_field: langcode
       sorts: {  }
       title: Content
       empty:
@@ -481,6 +460,7 @@ display:
           1: AND
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: default
     display_title: Master
     id: default
@@ -489,20 +469,24 @@ display:
     display_options:
       path: admin/content/node
       menu:
-        type: 'default tab'
+        type:
+          'default tab': 'default tab'
+          normal: '0'
+          tab: '0'
         title: Content
         description: ''
-        menu_name: admin
+        parent: ''
         weight: -10
-        context: ''
+        context: '0'
+        menu_name: admin
       tab_options:
-        type: normal
+        type: tab
         title: Content
         description: 'Find and manage content'
-        menu_name: admin
         weight: -10
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_1
diff --git a/core/modules/node/config/install/views.view.glossary.yml b/core/modules/node/config/install/views.view.glossary.yml
index 1625bdd..1bdb92a 100644
--- a/core/modules/node/config/install/views.view.glossary.yml
+++ b/core/modules/node/config/install/views.view.glossary.yml
@@ -113,8 +113,6 @@ display:
           hide_empty: false
           empty_zero: false
           hide_alter_empty: true
-          entity_type: node
-          entity_field: title
         name:
           id: name
           table: users_field_data
@@ -168,8 +166,6 @@ display:
           overwrite_anonymous: false
           anonymous_text: ''
           format_username: true
-          entity_type: user
-          entity_field: name
         changed:
           id: changed
           table: node_field_data
@@ -222,8 +218,6 @@ display:
           hide_alter_empty: true
           custom_date_format: ''
           timezone: ''
-          entity_type: node
-          entity_field: changed
       arguments:
         title:
           id: title
@@ -256,8 +250,6 @@ display:
             fail: 'not found'
           validate_options: {  }
           break_phrase: false
-          entity_type: node
-          entity_field: title
       relationships:
         uid:
           id: uid
@@ -347,8 +339,7 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: language
-          entity_type: node
-          entity_field: langcode
+      display_extenders: {  }
   attachment_1:
     id: attachment_1
     display_title: Attachment
@@ -400,14 +391,13 @@ display:
             fail: 'not found'
           validate_options: {  }
           break_phrase: false
-          entity_type: node
-          entity_field: title
       displays:
         default: default
         page_1: page_1
       inherit_arguments: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
   page_1:
     id: page_1
     display_title: Page
@@ -419,10 +409,16 @@ display:
         options: {  }
       path: glossary
       menu:
-        type: normal
+        type:
+          normal: normal
+          tab: '0'
+          'default tab': '0'
         title: Glossary
+        description: ''
+        parent: ''
         weight: 0
+        context: '0'
         menu_name: main
-        parent: ''
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
index ad1e38f..4b5caf0 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
@@ -70,6 +70,7 @@ display:
       arguments: {  }
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: default
     display_title: Master
     id: default
@@ -89,7 +90,10 @@ display:
           entity_type: node
           entity_field: nid
       menu:
-        type: tab
+        type:
+          tab: tab
+          normal: '0'
+          'default tab': '0'
         title: 'Test contextual link'
         description: ''
         menu_name: tools
@@ -97,6 +101,7 @@ display:
         context: '1'
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_1
diff --git a/core/modules/user/config/install/views.view.user_admin_people.yml b/core/modules/user/config/install/views.view.user_admin_people.yml
index ff62509..703ef86 100644
--- a/core/modules/user/config/install/views.view.user_admin_people.yml
+++ b/core/modules/user/config/install/views.view.user_admin_people.yml
@@ -188,7 +188,6 @@ display:
           empty_zero: false
           hide_alter_empty: true
           plugin_id: user_bulk_form
-          entity_type: user
         name:
           id: name
           table: users_field_data
@@ -242,8 +241,6 @@ display:
           anonymous_text: ''
           format_username: true
           plugin_id: user_name
-          entity_type: user
-          entity_field: name
         status:
           id: status
           table: users_field_data
@@ -297,8 +294,6 @@ display:
           type_custom_false: ''
           not: '0'
           plugin_id: boolean
-          entity_type: user
-          entity_field: status
         roles_target_id:
           id: roles_target_id
           table: user__roles
@@ -402,8 +397,6 @@ display:
           custom_date_format: ''
           timezone: ''
           plugin_id: date
-          entity_type: user
-          entity_field: created
         access:
           id: access
           table: users_field_data
@@ -456,8 +449,6 @@ display:
           custom_date_format: ''
           timezone: ''
           plugin_id: date
-          entity_type: user
-          entity_field: access
         edit_node:
           id: edit_node
           table: users
@@ -508,7 +499,6 @@ display:
           hide_alter_empty: true
           text: Edit
           plugin_id: user_link_edit
-          entity_type: user
         dropbutton:
           id: dropbutton
           table: views
@@ -617,8 +607,6 @@ display:
           hide_alter_empty: true
           link_to_user: false
           plugin_id: user_mail
-          entity_type: user
-          entity_field: mail
       filters:
         combine:
           id: combine
@@ -787,8 +775,6 @@ display:
                 operator: '='
                 value: '0'
           plugin_id: boolean
-          entity_type: user
-          entity_field: status
         uid_raw:
           id: uid_raw
           table: users
@@ -828,7 +814,6 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           plugin_id: numeric
-          entity_type: user
       sorts:
         created:
           id: created
@@ -843,8 +828,6 @@ display:
             label: ''
           granularity: second
           plugin_id: date
-          entity_type: user
-          entity_field: created
       title: People
       empty:
         area_text_custom:
@@ -875,6 +858,7 @@ display:
           1: AND
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
   page_1:
     display_plugin: page
     id: page_1
@@ -884,19 +868,23 @@ display:
       path: admin/people/list
       show_admin_links: false
       menu:
-        type: 'default tab'
+        type:
+          'default tab': 'default tab'
+          normal: '0'
+          tab: '0'
         title: List
         description: 'Find and manage people interacting with your site.'
-        menu_name: admin
+        parent: ''
         weight: -10
-        context: ''
+        context: '0'
+        menu_name: admin
       tab_options:
         type: normal
         title: People
         description: 'Manage user accounts, roles, and permissions.'
-        menu_name: admin
         weight: 0
       defaults:
         show_admin_links: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
diff --git a/core/modules/views/config/schema/views.display.schema.yml b/core/modules/views/config/schema/views.display.schema.yml
index 6531990..a14fef3 100644
--- a/core/modules/views/config/schema/views.display.schema.yml
+++ b/core/modules/views/config/schema/views.display.schema.yml
@@ -23,8 +23,11 @@ views.display.page:
       label: 'Menu'
       mapping:
         type:
-          type: string
+          type: sequence
           label: 'Type'
+          sequence:
+            - type: string
+              label: 'Menu type'
         title:
           type: text
           label: 'Title'
diff --git a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
index ef531b4..c0174b1 100644
--- a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
+++ b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
@@ -69,25 +69,27 @@ public function getDerivativeDefinitions($base_plugin_definition) {
 
       $executable->setDisplay($display_id);
       $menu = $executable->display_handler->getOption('menu');
-      if (in_array($menu['type'], array('tab', 'default tab'))) {
-        $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
-        $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
-
-        // Don't add a local task for views which override existing routes.
-        // @todo Alternative it could just change the existing entry.
-        if ($route_name != $plugin_id) {
-          continue;
-        }
+      foreach ($menu['type'] as $type) {
+        if (in_array($type, array('tab', 'default tab'))) {
+          $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
+          $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
+
+          // Don't add a local task for views which override existing routes.
+          // @todo Alternative it could just change the existing entry.
+          if ($route_name != $plugin_id) {
+            continue;
+          }
 
-        $this->derivatives[$plugin_id] = array(
-          'route_name' => $route_name,
-          'weight' => $menu['weight'],
-          'title' => $menu['title'],
-        ) + $base_plugin_definition;
+          $this->derivatives[$plugin_id] = array(
+            'route_name' => $route_name,
+            'weight' => $menu['weight'],
+            'title' => $menu['title'],
+          ) + $base_plugin_definition;
 
-        // Default local tasks have themselves as root tab.
-        if ($menu['type'] == 'default tab') {
-          $this->derivatives[$plugin_id]['base_route'] = $route_name;
+          // Default local tasks have themselves as root tab.
+          if ($type == 'default tab') {
+            $this->derivatives[$plugin_id]['base_route'] = $route_name;
+          }
         }
       }
     }
@@ -108,29 +110,31 @@ public function alterLocalTasks(&$local_tasks) {
       $menu = $executable->display_handler->getOption('menu');
 
       // We already have set the base_route for default tabs.
-      if (in_array($menu['type'], array('tab'))) {
-        $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
-        $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
-
-        // Don't add a local task for views which override existing routes.
-        if ($view_route_name != $plugin_id) {
-          unset($local_tasks[$plugin_id]);
-          continue;
-        }
+      foreach ($menu['type'] as $type) {
+        if (in_array('tab', array_filter($menu['type']))) {
+          $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
+          $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
+
+          // Don't add a local task for views which override existing routes.
+          if ($view_route_name != $plugin_id) {
+            unset($local_tasks[$plugin_id]);
+            continue;
+          }
 
-        // Find out the parent route.
-        // @todo Find out how to find both the root and parent tab.
-        $path = $executable->display_handler->getPath();
-        $split = explode('/', $path);
-        array_pop($split);
-        $path = implode('/', $split);
-
-        $pattern = '/' . str_replace('%', '{}', $path);
-        if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) {
-          foreach ($routes->all() as $name => $route) {
-            $local_tasks['views_view:' . $plugin_id]['base_route'] = $name;
-            // Skip after the first found route.
-            break;
+          // Find out the parent route.
+          // @todo Find out how to find both the root and parent tab.
+          $path = $executable->display_handler->getPath();
+          $split = explode('/', $path);
+          array_pop($split);
+          $path = implode('/', $split);
+
+          $pattern = '/' . str_replace('%', '{}', $path);
+          if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) {
+            foreach ($routes->all() as $name => $route) {
+              $local_tasks['views_view:' . $plugin_id]['base_route'] = $name;
+              // Skip after the first found route.
+              break;
+            }
           }
         }
       }
diff --git a/core/modules/views/src/Plugin/views/display/Page.php b/core/modules/views/src/Plugin/views/display/Page.php
index 3dd9a3d..adab3dc 100644
--- a/core/modules/views/src/Plugin/views/display/Page.php
+++ b/core/modules/views/src/Plugin/views/display/Page.php
@@ -45,7 +45,8 @@ protected function defineOptions() {
 
     $options['menu'] = array(
       'contains' => array(
-        'type' => array('default' => 'none'),
+        'type' => array('default' => array()),
+        // Do not translate menu and title as menu system will.
         'title' => array('default' => ''),
         'description' => array('default' => ''),
         'weight' => array('default' => 0),
@@ -97,23 +98,27 @@ public function optionsSummary(&$categories, &$options) {
     parent::optionsSummary($categories, $options);
 
     $menu = $this->getOption('menu');
-    if (!is_array($menu)) {
-      $menu = array('type' => 'none');
+    if (!is_array($menu) || empty($menu['type'])) {
+      $menu = array('type' => array('none'));
     }
-    switch ($menu['type']) {
-      case 'none':
-      default:
-        $menu_str = $this->t('No menu');
-        break;
-      case 'normal':
-        $menu_str = $this->t('Normal: @title', array('@title' => $menu['title']));
-        break;
-      case 'tab':
-      case 'default tab':
-        $menu_str = $this->t('Tab: @title', array('@title' => $menu['title']));
-        break;
+    $menus = array();
+    foreach (array_filter($menu['type']) as $type) {
+      switch ($type) {
+        case 'none':
+          $menus[] = $this->t('No menu');
+          break;
+        case 'normal':
+          $menus[] = $this->t('Normal: @title', array('@title' => $menu['title']));
+          break;
+        case 'tab':
+        case 'default tab':
+          $menus[] = $this->t('Tab: @title', array('@title' => $menu['title']));
+          break;
+      }
     }
 
+    $menu_str = implode(' | ', $menus);
+
     $options['menu'] = array(
       'category' => 'page',
       'title' => $this->t('Menu'),
@@ -122,7 +127,7 @@ public function optionsSummary(&$categories, &$options) {
 
     // This adds a 'Settings' link to the style_options setting if the style
     // has options.
-    if ($menu['type'] == 'default tab') {
+    if (!empty($menu['type']['default tab'])) {
       $options['menu']['setting'] = $this->t('Parent menu item');
       $options['menu']['links']['tab_options'] = $this->t('Change settings for the parent menu');
     }
@@ -143,16 +148,21 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
           '#tree' => TRUE,
         );
         $menu = $this->getOption('menu');
-        if (empty($menu)) {
-          $menu = array('type' => 'none', 'title' => '', 'weight' => 0);
-        }
+        $menu += array(
+          'type' => array('none'),
+          'title' => '',
+          'description' => '',
+          'weight' => 0,
+          'menu_name' => '',
+          'parent' => '',
+        );
         $form['menu']['type'] = array(
           '#prefix' => '<div class="views-left-30">',
           '#suffix' => '</div>',
-          '#title' => $this->t('Type'),
-          '#type' => 'radios',
+          '#title' => $this->t('Menu Link Types'),
+          '#type' => 'checkboxes',
+          '#multiple' => TRUE,
           '#options' => array(
-            'none' => $this->t('No menu entry'),
             'normal' => $this->t('Normal menu entry'),
             'tab' => $this->t('Menu tab'),
             'default tab' => $this->t('Default menu tab')
@@ -342,12 +352,14 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
 
     if ($form_state->get('section') == 'menu') {
       $path = $this->getOption('path');
-      $menu_type = $form_state->getValue(array('menu', 'type'));
-      if ($menu_type == 'normal' && strpos($path, '%') !== FALSE) {
+      $menu_types = array_filter($form_state->getValue(array('menu', 'type')));
+      $form_state->setValueForElement($form['menu']['type'], $menu_types);
+
+      if (in_array('normal', $menu_types) && strpos($path, '%') !== FALSE) {
         $form_state->setError($form['menu']['type'], $this->t('Views cannot create normal menu items for paths with a % in them.'));
       }
 
-      if ($menu_type == 'default tab' || $menu_type == 'tab') {
+      if (in_array('default tab', $menu_types) || in_array('tab', $menu_types)) {
         $bits = explode('/', $path);
         $last = array_pop($bits);
         if ($last == '%') {
@@ -355,7 +367,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
         }
       }
 
-      if ($menu_type != 'none' && $form_state->isValueEmpty(array('menu', 'title'))) {
+      if (!in_array('none', $menu_types) &&  $form_state->isValueEmpty(array('menu', 'title'))) {
         $form_state->setError($form['menu']['title'], $this->t('Title is required for this menu type.'));
       }
     }
@@ -373,7 +385,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
         list($menu['menu_name'], $menu['parent']) = explode(':', $menu['parent'], 2);
         $this->setOption('menu', $menu);
         // send ajax form to options page if we use it.
-        if ($form_state->getValue(array('menu', 'type')) == 'default tab') {
+        if ($form_state->getValue(array('menu', 'type', 'default tab'))) {
           $form_state->get('view')->addFormToStack('display', $this->display['id'], 'tab_options');
         }
         break;
@@ -390,13 +402,13 @@ public function validate() {
     $errors = parent::validate();
 
     $menu = $this->getOption('menu');
-    if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) {
+    if (!empty($menu['type']) && empty($menu['title'])) {
       $errors[] = $this->t('Display @display is set to use a menu but the menu link text is not set.', array('@display' => $this->display['display_title']));
     }
 
-    if ($menu['type'] == 'default tab') {
+    if (!empty($menu['type']['default tab'])) {
       $tab_options = $this->getOption('tab_options');
-      if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) {
+      if (!empty($tab_options['type']) && empty($menu['type']['none']) && empty($tab_options['title'])) {
         $errors[] = $this->t('Display @display is set to use a parent menu but the parent menu link text is not set.', array('@display' => $this->display['display_title']));
       }
     }
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index fd93c3c..b8f4656 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -108,7 +108,7 @@ public function getPath() {
   protected function isDefaultTabPath() {
     $menu = $this->getOption('menu');
     $tab_options = $this->getOption('tab_options');
-    return $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none';
+    return !empty($menu['type']['default tab']) && !empty($tab_options['type']) && $tab_options['type'] != 'none';
   }
 
   /**
@@ -302,33 +302,40 @@ public function getMenuLinks() {
     $view_id_display =  "{$view_id}.{$display_id}";
     $menu_link_id = 'views.' . str_replace('/', '.', $view_id_display);
 
-    if ($path) {
-      $menu = $this->getOption('menu');
-      if (!empty($menu['type']) && $menu['type'] == 'normal') {
-        $links[$menu_link_id] = array();
-        // Some views might override existing paths, so we have to set the route
-        // name based upon the altering.
-        $links[$menu_link_id] = array(
-          'route_name' => isset($view_route_names[$view_id_display]) ? $view_route_names[$view_id_display] : "view.$view_id_display",
-          // Identify URL embedded arguments and correlate them to a handler.
-          'load arguments'  => array($this->view->storage->id(), $this->display['id'], '%index'),
-          'id' => $menu_link_id,
-        );
-        $links[$menu_link_id]['title'] = $menu['title'];
-        $links[$menu_link_id]['description'] = $menu['description'];
-        $links[$menu_link_id]['parent'] = $menu['parent'];
-
-        if (isset($menu['weight'])) {
-          $links[$menu_link_id]['weight'] = intval($menu['weight']);
+    if ($path && ($menu = $this->getOption('menu')) && !empty($menu['type'])) {
+      foreach ($menu['type'] as $type) {
+        if ($type == 'normal') {
+          $links[$menu_link_id] = array();
+          // Some views might override existing paths, so we have to set the
+          // route name based upon the altering.
+          $view_id_display = "{$this->view->storage->id()}.{$this->display['id']}";
+          $links[$menu_link_id] = array(
+            'route_name' => isset($view_route_names[$view_id_display]) ? $view_route_names[$view_id_display] : "view.$view_id_display",
+            // Identify URL embedded arguments and correlate them to a handler.
+            'load arguments' => array(
+              $this->view->storage->id(),
+              $this->display['id'],
+              '%index'
+            ),
+            'id' => $menu_link_id,
+          );
+          $links[$menu_link_id]['title'] = $menu['title'];
+          $links[$menu_link_id]['description'] = $menu['description'];
+          $links[$menu_link_id]['parent'] = $menu['parent'];
+
+
+          if (isset($menu['weight'])) {
+            $links[$menu_link_id]['weight'] = intval($menu['weight']);
+          }
+
+          // Insert item into the proper menu.
+          $links[$menu_link_id]['menu_name'] = $menu['menu_name'];
+          // Keep track of where we came from.
+          $links[$menu_link_id]['metadata'] = array(
+            'view_id' => $view_id,
+            'display_id' => $display_id,
+          );
         }
-
-        // Insert item into the proper menu.
-        $links[$menu_link_id]['menu_name'] = $menu['menu_name'];
-        // Keep track of where we came from.
-        $links[$menu_link_id]['metadata'] = array(
-          'view_id' => $view_id,
-          'display_id' => $display_id,
-        );
       }
     }
 
diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
index bbf06ce..b6fdd11 100644
--- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
@@ -1049,7 +1049,7 @@ protected function pageDisplayOptions(array $form, FormStateInterface $form_stat
 
     // Generate the menu links settings if the user checked the link checkbox.
     if (!empty($page['link'])) {
-      $display_options['menu']['type'] = 'normal';
+      $display_options['menu']['type'] = array('normal' => 'normal');
       $display_options['menu']['title'] = $page['link_properties']['title'];
       $display_options['menu']['menu_name'] = $page['link_properties']['menu_name'];
     }
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml
index c9b40a5..af17cac 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml
@@ -24,6 +24,7 @@ display:
           plugin_id: numeric
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: default
     display_title: Master
     id: default
@@ -33,22 +34,26 @@ display:
       path: test_page_display_menu/default
       title: 'Test default page'
       menu:
-        type: 'default tab'
+        type:
+          'default tab': 'default tab'
+          normal: '0'
+          tab: '0'
         title: 'Test default tab'
         description: ''
-        menu_name: tools
+        parent: ''
         weight: -10
         context: '0'
+        menu_name: tools
       tab_options:
         type: normal
         title: 'Test parent path'
         description: ''
-        menu_name: tools
         weight: 0
       defaults:
         title: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_1
@@ -58,16 +63,21 @@ display:
       path: test_page_display_menu/local
       title: 'Test local page'
       menu:
-        type: tab
+        type:
+          tab: tab
+          normal: '0'
+          'default tab': '0'
         title: 'Test local tab'
         description: ''
-        menu_name: tools
+        parent: ''
         weight: 0
         context: '0'
+        menu_name: tools
       defaults:
         title: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_2
@@ -77,16 +87,21 @@ display:
       path: test_page_display_menu_link
       title: 'Test menu link'
       menu:
-        type: normal
+        type:
+          normal: normal
+          tab: '0'
+          'default tab': '0'
         title: 'Test menu link'
         description: ''
-        menu_name: tools
+        parent: ''
         weight: 0
         context: '0'
+        menu_name: tools
       defaults:
         title: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_3
@@ -96,17 +111,21 @@ display:
       path: test_page_display_menu/child
       title: 'Test page as child'
       menu:
-        type: normal
+        type:
+          normal: normal
+          tab: '0'
+          'default tab': '0'
         title: 'Test child'
-        parent: system.admin
         description: ''
-        menu_name: tools
+        parent: ''
         weight: 0
         context: '0'
+        menu_name: tools
       defaults:
         title: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_4
@@ -116,7 +135,10 @@ display:
       path: test-path
       title: 'Tests a menu with a non-existing parent'
       menu:
-        type: normal
+        type:
+          normal: normal
+          tab: '0'
+          'default tab': '0'
         title: 'Test child'
         parent: system.admin
         description: ''
@@ -127,6 +149,7 @@ display:
         title: false
       field_langcode: '***LANGUAGE_language_content***'
       field_langcode_add_to_query: null
+      display_extenders: {  }
     display_plugin: page
     display_title: Page
     id: page_4
diff --git a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
index c75d96f..486dba7 100644
--- a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
+++ b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
@@ -78,7 +78,7 @@ public function testGetDerivativeDefinitionsWithoutLocalTask() {
     $display_plugin->expects($this->once())
       ->method('getOption')
       ->with('menu')
-      ->will($this->returnValue(array('type' => 'normal')));
+      ->will($this->returnValue(array('type' => array('normal' => 'normal'))));
     $executable->display_handler = $display_plugin;
 
     $result = array(array($executable, 'page_1'));
@@ -110,7 +110,7 @@ public function testGetDerivativeDefinitionsWithLocalTask() {
     $display_plugin->expects($this->once())
       ->method('getOption')
       ->with('menu')
-      ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title')));
+      ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12, 'title' => 'Example title')));
     $executable->display_handler = $display_plugin;
 
     $result = array(array($executable, 'page_1'));
@@ -155,7 +155,7 @@ public function testGetDerivativeDefinitionsWithOverrideRoute() {
     $display_plugin->expects($this->once())
       ->method('getOption')
       ->with('menu')
-      ->will($this->returnValue(array('type' => 'tab', 'weight' => 12)));
+      ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12)));
     $executable->display_handler = $display_plugin;
 
     $result = array(array($executable, 'page_1'));
@@ -196,7 +196,7 @@ public function testGetDerivativeDefinitionsWithDefaultLocalTask() {
     $display_plugin->expects($this->exactly(2))
       ->method('getOption')
       ->with('menu')
-      ->will($this->returnValue(array('type' => 'default tab', 'weight' => 12, 'title' => 'Example title')));
+      ->will($this->returnValue(array('type' => array('default tab' => 'default tab'), 'weight' => 12, 'title' => 'Example title')));
     $executable->display_handler = $display_plugin;
 
     $result = array(array($executable, 'page_1'));
@@ -257,7 +257,7 @@ public function testGetDerivativeDefinitionsWithExistingLocalTask() {
     $display_plugin->expects($this->exactly(2))
       ->method('getOption')
       ->with('menu')
-      ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title')));
+      ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12, 'title' => 'Example title')));
     $display_plugin->expects($this->once())
       ->method('getPath')
       ->will($this->returnValue('path/example'));
diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php
index 71b2035..14e2992 100644
--- a/core/modules/views_ui/src/Tests/DisplayPathTest.php
+++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php
@@ -116,19 +116,27 @@ public function testMenuOptions() {
     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => $random_string), t('Apply'));
     $this->drupalGet('admin/structure/views/view/test_view');
 
-    $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type]' => 'default tab', 'menu[title]' => 'Test tab title'), t('Apply'));
+    $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type][default tab]' => 'default tab', 'menu[title]' => 'Test tab title'), t('Apply'));
     $this->assertResponse(200);
     $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options');
 
-    $this->drupalPostForm(NULL, array('tab_options[type]' => 'tab', 'tab_options[title]' => $this->randomString()), t('Apply'));
+    $this->drupalPostForm(NULL, array('tab_options[type]' => 'normal', 'tab_options[title]' => 'Test tab title'), t('Apply'));
     $this->assertResponse(200);
     $this->assertUrl('admin/structure/views/view/test_view/edit/page_1');
-
-    $this->drupalGet('admin/structure/views/view/test_view');
     $this->assertLink(t('Tab: @title', array('@title' => 'Test tab title')));
     // If it's a default tab, it should also have an additional settings link.
     $this->assertLinkByHref('admin/structure/views/nojs/display/test_view/page_1/tab_options');
 
+    // It can be default tab and normal menu item as well.
+    $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type][normal]' => 'normal', 'menu[title]' => 'Test'), t('Apply'));
+    $this->assertResponse(200);
+    $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options');
+
+    $this->drupalPostForm(NULL, array('tab_options[type]' => 'normal', 'tab_options[title]' => 'Test tab title'), t('Apply'));
+    $this->assertResponse(200);
+    $this->assertUrl('admin/structure/views/view/test_view/edit/page_1');
+    $this->assertLink(t('Normal: @title | Tab: @title', array('@title' => 'Test')));
+
     // Ensure that you can select a parent in case the parent does not exist.
     $this->drupalGet('admin/structure/views/nojs/display/test_page_display_menu/page_5/menu');
     $this->assertResponse(200);
