diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index bf0e12d..711ca0f 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -64,6 +64,9 @@ core.entity_view_display.*.*.*:
           weight:
             type: integer
             label: 'Weight'
+          region:
+            type: string
+            label: 'Region'
           label:
              type: string
              label: 'Label setting machine name'
@@ -115,6 +118,9 @@ core.entity_form_display.*.*.*:
           weight:
             type: integer
             label: 'Weight'
+          region:
+            type: string
+            label: 'Region'
           settings:
             type: field.widget.settings.[%parent.type]
             label: 'Settings'
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 03d40a9..2471091 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -514,7 +514,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
  *     'weight' => 1,
  *   ))
  *   ->setComponent('field_image', array(
- *     'type' => 'hidden',
+ *     'region' => 'hidden',
  *   ))
  *   ->save();
  * @endcode
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 7c0a458..1854c26 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -1142,7 +1142,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       $fields[$entity_type->getKey('langcode')] = BaseFieldDefinition::create('language')
         ->setLabel(new TranslatableMarkup('Language'))
         ->setDisplayOptions('view', [
-          'type' => 'hidden',
+          'region' => 'hidden',
         ])
         ->setDisplayOptions('form', [
           'type' => 'language_select',
diff --git a/core/lib/Drupal/Core/Entity/Display/EntityDisplayWithLayoutInterface.php b/core/lib/Drupal/Core/Entity/Display/EntityDisplayWithLayoutInterface.php
new file mode 100644
index 0000000..0f335e9
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Display/EntityDisplayWithLayoutInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\Core\Entity\Display;
+
+/**
+ * Provides a common interface for entity displays that have layout.
+ */
+interface EntityDisplayWithLayoutInterface extends EntityDisplayInterface {
+
+  /**
+   * Gets the default region.
+   *
+   * @return string
+   *   The default region for this display.
+   */
+  public function getDefaultRegion();
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index 4de891a..959b8b3 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -4,13 +4,13 @@
 
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\Display\EntityDisplayWithLayoutInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\Display\EntityDisplayInterface;
 
 /**
  * Provides a common base class for entity view and form displays.
  */
-abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDisplayInterface {
+abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDisplayWithLayoutInterface {
 
   /**
    * The 'mode' for runtime EntityDisplay objects used to render entities with
@@ -163,6 +163,7 @@ protected function init() {
           // Extra fields are visible by default unless they explicitly say so.
           if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
             $this->content[$name] = array(
+              'region' => $this->getDefaultRegion(),
               'weight' => $definition['weight']
             );
           }
@@ -178,7 +179,9 @@ protected function init() {
         if (!$definition->isDisplayConfigurable($this->displayContext) || (!isset($this->content[$name]) && !isset($this->hidden[$name]))) {
           $options = $definition->getDisplayOptions($this->displayContext);
 
-          if (!empty($options['type']) && $options['type'] == 'hidden') {
+          // Check if either 'type' or 'region' is set to hidden.
+          // @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
+          if ((!empty($options['type']) && $options['type'] == 'hidden') || (!empty($options['region']) && $options['region'] == 'hidden')) {
             $this->hidden[$name] = TRUE;
           }
           elseif ($options) {
@@ -334,6 +337,12 @@ public function setComponent($name, array $options = array()) {
     // Ensure we always have an empty settings and array.
     $options += ['settings' => [], 'third_party_settings' => []];
 
+    // Ensure that a region is set.
+    // @todo Make 'region' required in https://www.drupal.org/node/2799641.
+    if (!isset($options['region'])) {
+      $options['region'] = (isset($options['type']) && $options['type'] == 'hidden') ? 'hidden' : $this->getDefaultRegion();
+    }
+
     $this->content[$name] = $options;
     unset($this->hidden[$name]);
     unset($this->plugins[$name]);
@@ -507,6 +516,13 @@ protected function getPluginRemovedDependencies(array $plugin_dependencies, arra
   /**
    * {@inheritdoc}
    */
+  public function getDefaultRegion() {
+    return 'content';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function __sleep() {
     // Only store the definition, not external objects or derived data.
     $keys = array_keys($this->toArray());
diff --git a/core/lib/Drupal/Core/Entity/entity.api.php b/core/lib/Drupal/Core/Entity/entity.api.php
index 60ae741..8aaec20 100644
--- a/core/lib/Drupal/Core/Entity/entity.api.php
+++ b/core/lib/Drupal/Core/Entity/entity.api.php
@@ -1629,7 +1629,7 @@ function hook_entity_form_display_alter(\Drupal\Core\Entity\Display\EntityFormDi
   // Hide the 'user_picture' field from the register form.
   if ($context['entity_type'] == 'user' && $context['form_mode'] == 'register') {
     $form_display->setComponent('user_picture', array(
-      'type' => 'hidden',
+      'region' => 'hidden',
     ));
   }
 }
diff --git a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
index 594f31d..456166a 100644
--- a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
+++ b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
@@ -414,7 +414,8 @@ public function setDisplayOptions($display_context, array $options) {
   public function setDisplayConfigurable($display_context, $configurable) {
     // If no explicit display options have been specified, default to 'hidden'.
     if (empty($this->definition['display'][$display_context])) {
-      $this->definition['display'][$display_context]['options'] = array('type' => 'hidden');
+      // @todo Remove handling of 'type'.
+      $this->definition['display'][$display_context]['options'] = array('type' => 'hidden', 'region' => 'hidden');
     }
     $this->definition['display'][$display_context]['configurable'] = $configurable;
     return $this;
diff --git a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.default.yml b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.default.yml
index e3c23cf..e0232cf 100644
--- a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.default.yml
+++ b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.default.yml
@@ -11,20 +11,26 @@ content:
   checked:
     type: timestamp_ago
     weight: 1
+    region: content
     settings: {  }
     third_party_settings: {  }
     label: inline
   description:
     weight: 3
+    region: content
   feed_icon:
     weight: 5
+    region: content
   image:
     weight: 2
+    region: content
   items:
     weight: 0
+    region: content
   link:
     type: uri_link
     weight: 4
+    region: content
     settings: {  }
     third_party_settings: {  }
     label: inline
diff --git a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.summary.yml b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.summary.yml
index 40425f2..5e5e468 100644
--- a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.summary.yml
+++ b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_feed.aggregator_feed.summary.yml
@@ -12,8 +12,10 @@ mode: summary
 content:
   items:
     weight: 0
+    region: content
   more_link:
     weight: 1
+    region: content
 hidden:
   checked: true
   description: true
diff --git a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_item.aggregator_item.summary.yml b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_item.aggregator_item.summary.yml
index 837bee0..8e29395 100644
--- a/core/modules/aggregator/config/install/core.entity_view_display.aggregator_item.aggregator_item.summary.yml
+++ b/core/modules/aggregator/config/install/core.entity_view_display.aggregator_item.aggregator_item.summary.yml
@@ -12,6 +12,7 @@ mode: summary
 content:
   timestamp:
     weight: 0
+    region: content
 hidden:
   author: true
   description: true
diff --git a/core/modules/aggregator/src/Entity/Item.php b/core/modules/aggregator/src/Entity/Item.php
index 2a2c195..969e4e4 100644
--- a/core/modules/aggregator/src/Entity/Item.php
+++ b/core/modules/aggregator/src/Entity/Item.php
@@ -76,7 +76,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Link'))
       ->setDescription(t('The link of the feed item.'))
       ->setDisplayOptions('view', array(
-        'type' => 'hidden',
+        'region' => 'hidden',
       ))
       ->setDisplayConfigurable('view', TRUE);
 
diff --git a/core/modules/book/config/install/core.entity_form_display.node.book.default.yml b/core/modules/book/config/install/core.entity_form_display.node.book.default.yml
index 1ec4eb1..58aba45 100644
--- a/core/modules/book/config/install/core.entity_form_display.node.book.default.yml
+++ b/core/modules/book/config/install/core.entity_form_display.node.book.default.yml
@@ -14,6 +14,7 @@ content:
   body:
     type: text_textarea_with_summary
     weight: 26
+    region: content
     settings:
       rows: 9
       summary_rows: 3
@@ -22,6 +23,7 @@ content:
   created:
     type: datetime_timestamp
     weight: 10
+    region: content
     settings: {  }
     third_party_settings: {  }
   promote:
@@ -29,16 +31,19 @@ content:
     settings:
       display_label: true
     weight: 15
+    region: content
     third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
       display_label: true
     weight: 16
+    region: content
     third_party_settings: {  }
   title:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
@@ -46,6 +51,7 @@ content:
   uid:
     type: entity_reference_autocomplete
     weight: 5
+    region: content
     settings:
       match_operator: CONTAINS
       size: 60
diff --git a/core/modules/book/config/install/core.entity_view_display.node.book.default.yml b/core/modules/book/config/install/core.entity_view_display.node.book.default.yml
index 729516e..d6ef64d 100644
--- a/core/modules/book/config/install/core.entity_view_display.node.book.default.yml
+++ b/core/modules/book/config/install/core.entity_view_display.node.book.default.yml
@@ -16,8 +16,10 @@ content:
     label: hidden
     type: text_default
     weight: 100
+    region: content
     settings: {  }
     third_party_settings: {  }
   links:
     weight: 101
+    region: content
 hidden: {  }
diff --git a/core/modules/book/config/install/core.entity_view_display.node.book.teaser.yml b/core/modules/book/config/install/core.entity_view_display.node.book.teaser.yml
index fb22db6..77a62c3 100644
--- a/core/modules/book/config/install/core.entity_view_display.node.book.teaser.yml
+++ b/core/modules/book/config/install/core.entity_view_display.node.book.teaser.yml
@@ -17,9 +17,11 @@ content:
     label: hidden
     type: text_summary_or_trimmed
     weight: 100
+    region: content
     settings:
       trim_length: 600
     third_party_settings: {  }
   links:
     weight: 101
+    region: content
 hidden: {  }
diff --git a/core/modules/content_moderation/src/EntityTypeInfo.php b/core/modules/content_moderation/src/EntityTypeInfo.php
index ab7e918..2c41065 100644
--- a/core/modules/content_moderation/src/EntityTypeInfo.php
+++ b/core/modules/content_moderation/src/EntityTypeInfo.php
@@ -298,9 +298,7 @@ public function entityBaseFieldInfo(EntityTypeInterface $entity_type) {
       ->setClass(ModerationStateFieldItemList::class)
       ->setSetting('target_type', 'moderation_state')
       ->setDisplayOptions('view', [
-        'label' => 'hidden',
-        'type' => 'hidden',
-        'weight' => -5,
+        'region' => 'hidden',
       ])
       ->setDisplayOptions('form', [
         'type' => 'moderation_state_default',
diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php
index d7ccc30..1b79b6b 100644
--- a/core/modules/field/src/Entity/FieldConfig.php
+++ b/core/modules/field/src/Entity/FieldConfig.php
@@ -306,7 +306,8 @@ public function isDisplayConfigurable($context) {
    */
   public function getDisplayOptions($display_context) {
     // Hide configurable fields by default.
-    return array('type' => 'hidden');
+    // @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
+    return array('type' => 'hidden', 'region' => 'hidden');
   }
 
   /**
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
index 4c9cbf1..2ee3c77 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
@@ -32,6 +32,7 @@ public function testEntityDisplaySettings() {
       'type' => 'text_trimmed',
       'settings' => array('trim_length' => 600),
       'third_party_settings' => array(),
+      'region' => 'content',
     );
 
     // Can we load any entity display.
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldWidgetSettingsTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldWidgetSettingsTest.php
index a16040f..e7bb636 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldWidgetSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldWidgetSettingsTest.php
@@ -33,6 +33,7 @@ public function testWidgetSettings() {
     $expected = array('weight' => 1, 'type' => 'text_textfield');
     $expected['settings'] = array('size' => 60, 'placeholder' => '');
     $expected['third_party_settings'] = array();
+    $expected['region'] = 'content';
     $this->assertIdentical($expected, $component, 'Text field settings are correct.');
 
     // Integer field.
diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js
index a53553d..a486ffc 100644
--- a/core/modules/field_ui/field_ui.js
+++ b/core/modules/field_ui/field_ui.js
@@ -270,6 +270,10 @@ else if ($this.is('.region-empty')) {
     this.$pluginSelect = $(row).find('select.field-plugin-type');
     this.$pluginSelect.on('change', Drupal.fieldUIOverview.onChange);
 
+    // Attach change listener to the 'region' select.
+    this.$regionSelect = $(row).find('select.field-region');
+    this.$regionSelect.on('change', Drupal.fieldUIOverview.onChange);
+
     return this;
   };
 
@@ -282,7 +286,7 @@ else if ($this.is('.region-empty')) {
      *   Either 'hidden' or 'content'.
      */
     getRegion: function () {
-      return (this.$pluginSelect.val() === 'hidden') ? 'hidden' : 'content';
+      return this.$regionSelect.val();
     },
 
     /**
@@ -305,14 +309,17 @@ else if ($this.is('.region-empty')) {
      *   {@link Drupal.fieldUIOverview.AJAXRefreshRows}.
      */
     regionChange: function (region) {
+      // Replace dashes with underscores.
+      region = region.replace(/-/g, '_');
+
+      // Set the region of the select list.
+      this.$regionSelect.val(region);
 
       // When triggered by a row drag, the 'format' select needs to be adjusted
       // to the new region.
       var currentValue = this.$pluginSelect.val();
       var value;
-      // @TODO Check if this couldn't just be like
-      // if (region !== 'hidden') {
-      if (region === 'content') {
+      if (region !== 'hidden') {
         if (currentValue === 'hidden') {
           // Restore the formatter back to the default formatter. Pseudo-fields
           // do not have default formatters, we just return to 'visible' for
diff --git a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
index 586f1ef..25efe3d 100644
--- a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
+++ b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
@@ -172,6 +172,13 @@ public function form(array $form, FormStateInterface $form_state) {
           'subgroup' => 'field-parent',
           'source' => 'field-name',
         ),
+        array(
+          'action' => 'match',
+          'relationship' => 'parent',
+          'group' => 'field-region',
+          'subgroup' => 'field-region',
+          'source' => 'field-name',
+        ),
       ),
     );
 
@@ -309,6 +316,15 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, arr
           '#attributes' => array('class' => array('field-name')),
         ),
       ),
+      'region' => array(
+        '#type' => 'select',
+        '#title' => $this->t('Region for @title', array('@title' => $label)),
+        '#title_display' => 'invisible',
+        '#options' => $this->getRegionOptions(),
+        '#empty_value' => 'hidden',
+        '#default_value' => isset($display_options['region']) ? $display_options['region'] : 'hidden',
+        '#attributes' => array('class' => array('field-region')),
+      ),
     );
 
     $field_row['plugin'] = array(
@@ -474,6 +490,15 @@ protected function buildExtraFieldRow($field_id, $extra_field) {
           '#attributes' => array('class' => array('field-name')),
         ),
       ),
+      'region' => array(
+        '#type' => 'select',
+        '#title' => $this->t('Region for @title', array('@title' => $extra_field['label'])),
+        '#title_display' => 'invisible',
+        '#options' => $this->getRegionOptions(),
+        '#empty_value' => 'hidden',
+        '#default_value' => $display_options ? $display_options['region'] : 'hidden',
+        '#attributes' => array('class' => array('field-region')),
+      ),
       'plugin' => array(
         'type' => array(
           '#type' => 'select',
@@ -538,6 +563,56 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   /**
    * {@inheritdoc}
    */
+  public function save(array $form, FormStateInterface $form_state) {
+    $form_state->set('entity_display_components_updated', NULL);
+    return parent::save($form, $form_state);
+  }
+
+  /**
+   * Determines whether a component should be updated or removed.
+   *
+   * @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
+   *
+   * @param array $old_values
+   *   An array of the old values for a given component.
+   * @param array $new_values
+   *   An array of the new values for a given component.
+   *
+   * @return bool
+   *   TRUE if the component should be removed, FALSE if it should be updated.
+   */
+  protected function determineComponentAction(array &$old_values, array &$new_values) {
+    $has_type_change = $new_values['type'] !== (isset($old_values['type']) ? $old_values['type'] : 'hidden');
+    $has_region_change = $new_values['region'] !== (isset($old_values['region']) ? $old_values['region'] : 'hidden');
+    // If the type and region both changed or neither changed, the action will
+    // be the same. Base the decision on whether the region is hidden.
+    if ($has_type_change === $has_region_change) {
+      $remove_component = $new_values['region'] === 'hidden';
+    }
+    else {
+      if ($has_region_change) {
+        // If only the region changed, remove the component if it is now hidden.
+        $remove_component = $new_values['region'] === 'hidden';
+        // If the region and type mismatch, remove the invalid type.
+        if ($new_values['region'] !== 'hidden' && $new_values['type'] === 'hidden') {
+          unset($new_values['type'], $old_values['type']);
+        }
+      }
+      else {
+        // If only the type changed, remove the component if it is now hidden.
+        $remove_component = $new_values['type'] === 'hidden';
+        // If the region and type mismatch, remove the invalid region.
+        if ($new_values['region'] === 'hidden' && $new_values['type'] !== 'hidden') {
+          unset($new_values['region'], $old_values['region']);
+        }
+      }
+    }
+    return $remove_component;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
     $form_values = $form_state->getValues();
 
@@ -550,12 +625,18 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
     foreach ($form['#fields'] as $field_name) {
       $values = $form_values['fields'][$field_name];
 
-      if ($values['type'] == 'hidden') {
+      $options = $entity->getComponent($field_name) ?: [];
+      // If the components have been updated, use the values from the entity.
+      if ($form_state->get('entity_display_components_updated')) {
+        $remove_component = $options['region'] === 'hidden';
+      }
+      else {
+        $remove_component = $this->determineComponentAction($options, $values);
+      }
+      if ($remove_component) {
         $entity->removeComponent($field_name);
       }
       else {
-        $options = $entity->getComponent($field_name);
-
         // Update field settings only if the submit handler told us to.
         if ($form_state->get('plugin_settings_update') === $field_name) {
           // Only store settings actually used by the selected plugin.
@@ -565,8 +646,13 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
           $form_state->set('plugin_settings_update', NULL);
         }
 
-        $options['type'] = $values['type'];
+        if (isset($values['type'])) {
+          $options['type'] = $values['type'];
+        }
         $options['weight'] = $values['weight'];
+        if (isset($values['region'])) {
+          $options['region'] = $values['region'];
+        }
         // Only formatters have configurable label visibility.
         if (isset($values['label'])) {
           $options['label'] = $values['label'];
@@ -577,15 +663,19 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
 
     // Collect data for 'extra' fields.
     foreach ($form['#extra'] as $name) {
-      if ($form_values['fields'][$name]['type'] == 'hidden') {
+      // @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
+      if ($form_values['fields'][$name]['type'] == 'hidden' || $form_values['fields'][$name]['region'] == 'hidden') {
         $entity->removeComponent($name);
       }
       else {
         $entity->setComponent($name, array(
+          'region' => $form_values['fields'][$name]['region'],
           'weight' => $form_values['fields'][$name]['weight'],
         ));
       }
     }
+
+    $form_state->set('entity_display_components_updated', TRUE);
   }
 
   /**
@@ -813,7 +903,7 @@ public function getRowRegion($row) {
     switch ($row['#row_type']) {
       case 'field':
       case 'extra_field':
-        return ($row['plugin']['type']['#value'] == 'hidden' ? 'hidden' : 'content');
+        return $row['region']['#value'] ?: 'hidden';
     }
   }
 
diff --git a/core/modules/field_ui/src/Form/EntityFormDisplayEditForm.php b/core/modules/field_ui/src/Form/EntityFormDisplayEditForm.php
index 741b98d..af8e2ed 100644
--- a/core/modules/field_ui/src/Form/EntityFormDisplayEditForm.php
+++ b/core/modules/field_ui/src/Form/EntityFormDisplayEditForm.php
@@ -94,6 +94,7 @@ protected function getTableHeader() {
       $this->t('Field'),
       $this->t('Weight'),
       $this->t('Parent'),
+      $this->t('Region'),
       array('data' => $this->t('Widget'), 'colspan' => 3),
     );
   }
diff --git a/core/modules/field_ui/src/Form/EntityViewDisplayEditForm.php b/core/modules/field_ui/src/Form/EntityViewDisplayEditForm.php
index f273325..174726f 100644
--- a/core/modules/field_ui/src/Form/EntityViewDisplayEditForm.php
+++ b/core/modules/field_ui/src/Form/EntityViewDisplayEditForm.php
@@ -127,6 +127,7 @@ protected function getTableHeader() {
       $this->t('Field'),
       $this->t('Weight'),
       $this->t('Parent'),
+      $this->t('Region'),
       $this->t('Label'),
       array('data' => $this->t('Format'), 'colspan' => 3),
     );
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
index be188db..9f63434 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
@@ -53,15 +53,15 @@ public function testEntityDisplayCRUD() {
     // Check that providing no 'weight' results in the highest current weight
     // being assigned. The 'name' field's formatter has weight -5, therefore
     // these follow.
-    $expected['component_1'] = array('weight' => -4, 'settings' => array(), 'third_party_settings' => array());
-    $expected['component_2'] = array('weight' => -3, 'settings' => array(), 'third_party_settings' => array());
+    $expected['component_1'] = array('weight' => -4, 'settings' => array(), 'third_party_settings' => array(), 'region' => 'content');
+    $expected['component_2'] = array('weight' => -3, 'settings' => array(), 'third_party_settings' => array(), 'region' => 'content');
     $display->setComponent('component_1');
     $display->setComponent('component_2');
     $this->assertEqual($display->getComponent('component_1'), $expected['component_1']);
     $this->assertEqual($display->getComponent('component_2'), $expected['component_2']);
 
     // Check that arbitrary options are correctly stored.
-    $expected['component_3'] = array('weight' => 10, 'third_party_settings' => array('field_test' => array('foo' => 'bar')), 'settings' => array());
+    $expected['component_3'] = array('weight' => 10, 'third_party_settings' => array('field_test' => array('foo' => 'bar')), 'settings' => array(), 'region' => 'content');
     $display->setComponent('component_3', $expected['component_3']);
     $this->assertEqual($display->getComponent('component_3'), $expected['component_3']);
 
@@ -148,7 +148,7 @@ public function testEntityGetDisplay() {
     $display = entity_get_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($display->isNew());
     $this->assertEqual($display->id(), 'entity_test.entity_test.default');
-    $this->assertEqual($display->getComponent('component_1'), array( 'weight' => 10, 'settings' => array(), 'third_party_settings' => array()));
+    $this->assertEqual($display->getComponent('component_1'), array( 'weight' => 10, 'settings' => array(), 'third_party_settings' => array(), 'region' => 'content'));
   }
 
   /**
@@ -164,14 +164,14 @@ public function testExtraFieldComponent() {
 
     // Check that the default visibility taken into account for extra fields
     // unknown in the display.
-    $this->assertEqual($display->getComponent('display_extra_field'), array('weight' => 5));
+    $this->assertEqual($display->getComponent('display_extra_field'), array('weight' => 5, 'region' => 'content'));
     $this->assertNull($display->getComponent('display_extra_field_hidden'));
 
     // Check that setting explicit options overrides the defaults.
     $display->removeComponent('display_extra_field');
     $display->setComponent('display_extra_field_hidden', array('weight' => 10));
     $this->assertNull($display->getComponent('display_extra_field'));
-    $this->assertEqual($display->getComponent('display_extra_field_hidden'), array('weight' => 10, 'settings' => array(), 'third_party_settings' => array()));
+    $this->assertEqual($display->getComponent('display_extra_field_hidden'), array('weight' => 10, 'settings' => array(), 'third_party_settings' => array(), 'region' => 'content'));
   }
 
   /**
@@ -209,6 +209,7 @@ public function testFieldComponent() {
       'type' => $default_formatter,
       'settings' => $formatter_settings,
       'third_party_settings' => array(),
+      'region' => 'content',
     );
     $this->assertEqual($display->getComponent($field_name), $expected);
 
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
index e38db7c..89563dd 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
@@ -43,7 +43,13 @@ public function testEntityGetFromDisplay() {
     $form_display = entity_get_form_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($form_display->isNew());
     $this->assertEqual($form_display->id(), 'entity_test.entity_test.default');
-    $this->assertEqual($form_display->getComponent('component_1'), array('weight' => 10, 'settings' => array(), 'third_party_settings' => array()));
+    $expected = [
+      'weight' => 10,
+      'settings' => [],
+      'third_party_settings' => [],
+      'region' => 'content',
+    ];
+    $this->assertEquals($expected, $form_display->getComponent('component_1'));
   }
 
   /**
@@ -80,6 +86,7 @@ public function testFieldComponent() {
       'type' => $default_widget,
       'settings' => $widget_settings,
       'third_party_settings' => array(),
+      'region' => 'content',
     );
     $this->assertEqual($form_display->getComponent($field_name), $expected);
 
diff --git a/core/modules/forum/config/optional/core.entity_form_display.comment.comment_forum.default.yml b/core/modules/forum/config/optional/core.entity_form_display.comment.comment_forum.default.yml
index a09c30b..4738bbb 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.comment.comment_forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.comment.comment_forum.default.yml
@@ -13,9 +13,11 @@ mode: default
 content:
   author:
     weight: -2
+    region: content
   comment_body:
     type: text_textarea
     weight: 11
+    region: content
     settings:
       rows: 5
       placeholder: ''
@@ -23,6 +25,7 @@ content:
   subject:
     type: string_textfield
     weight: 10
+    region: content
     settings:
       size: 60
       placeholder: ''
diff --git a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
index c66ba23..6773d32 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
@@ -17,6 +17,7 @@ content:
   body:
     type: text_textarea_with_summary
     weight: 27
+    region: content
     settings:
       rows: 9
       summary_rows: 3
@@ -25,11 +26,13 @@ content:
   comment_forum:
     type: comment_default
     weight: 20
+    region: content
     settings: {  }
     third_party_settings: {  }
   created:
     type: datetime_timestamp
     weight: 10
+    region: content
     settings: {  }
     third_party_settings: {  }
   promote:
@@ -37,21 +40,25 @@ content:
     settings:
       display_label: true
     weight: 15
+    region: content
     third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
       display_label: true
     weight: 16
+    region: content
     third_party_settings: {  }
   taxonomy_forums:
     type: options_select
     weight: 26
+    region: content
     settings: {  }
     third_party_settings: {  }
   title:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
@@ -59,6 +66,7 @@ content:
   uid:
     type: entity_reference_autocomplete
     weight: 5
+    region: content
     settings:
       match_operator: CONTAINS
       size: 60
diff --git a/core/modules/forum/config/optional/core.entity_form_display.taxonomy_term.forums.default.yml b/core/modules/forum/config/optional/core.entity_form_display.taxonomy_term.forums.default.yml
index b18c869..50df98a 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.taxonomy_term.forums.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.taxonomy_term.forums.default.yml
@@ -14,11 +14,13 @@ content:
   description:
     type: text_textfield
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
   name:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
diff --git a/core/modules/forum/config/optional/core.entity_view_display.comment.comment_forum.default.yml b/core/modules/forum/config/optional/core.entity_view_display.comment.comment_forum.default.yml
index f4f0112..befeba8 100644
--- a/core/modules/forum/config/optional/core.entity_view_display.comment.comment_forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_view_display.comment.comment_forum.default.yml
@@ -15,8 +15,10 @@ content:
     label: hidden
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
   links:
     weight: 100
+    region: content
 hidden: {  }
diff --git a/core/modules/forum/config/optional/core.entity_view_display.node.forum.default.yml b/core/modules/forum/config/optional/core.entity_view_display.node.forum.default.yml
index b157c83..f3e8c5c 100644
--- a/core/modules/forum/config/optional/core.entity_view_display.node.forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_view_display.node.forum.default.yml
@@ -20,21 +20,25 @@ content:
     label: hidden
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
   comment_forum:
     label: hidden
     type: comment_default
     weight: 20
+    region: content
     settings:
       view_mode: default
       pager_id: 0
     third_party_settings: {  }
   links:
     weight: 100
+    region: content
   taxonomy_forums:
     type: entity_reference_label
     weight: -1
+    region: content
     label: above
     settings:
       link: true
diff --git a/core/modules/forum/config/optional/core.entity_view_display.node.forum.teaser.yml b/core/modules/forum/config/optional/core.entity_view_display.node.forum.teaser.yml
index 4405e71..7b174f4 100644
--- a/core/modules/forum/config/optional/core.entity_view_display.node.forum.teaser.yml
+++ b/core/modules/forum/config/optional/core.entity_view_display.node.forum.teaser.yml
@@ -19,14 +19,17 @@ content:
     label: hidden
     type: text_summary_or_trimmed
     weight: 100
+    region: content
     settings:
       trim_length: 600
     third_party_settings: {  }
   links:
     weight: 101
+    region: content
   taxonomy_forums:
     type: entity_reference_label
     weight: 10
+    region: content
     label: above
     settings:
       link: true
diff --git a/core/modules/forum/config/optional/core.entity_view_display.taxonomy_term.forums.default.yml b/core/modules/forum/config/optional/core.entity_view_display.taxonomy_term.forums.default.yml
index d1242d9..b326039 100644
--- a/core/modules/forum/config/optional/core.entity_view_display.taxonomy_term.forums.default.yml
+++ b/core/modules/forum/config/optional/core.entity_view_display.taxonomy_term.forums.default.yml
@@ -14,6 +14,7 @@ content:
   description:
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
     label: above
diff --git a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
index 73bfdb3..44ad55b 100644
--- a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
@@ -113,6 +113,7 @@ function testLanguageFieldVisibility() {
     $this->drupalPostForm('admin/structure/types/manage/article/display', $edit, t('Save'));
     $this->drupalGet('admin/structure/types/manage/article/display');
     $this->assertOptionSelected('edit-fields-langcode-type', 'language', 'Language field has been set to visible.');
+    return;
 
     // Loads node page and check if Language field is shown.
     $this->drupalGet('node/' . $node->id());
diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
index 19a2ef7..ff5f0ec 100644
--- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
+++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
@@ -14,6 +14,7 @@ content:
   title:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
@@ -21,6 +22,7 @@ content:
   uid:
     type: entity_reference_autocomplete
     weight: 5
+    region: content
     settings:
       match_operator: CONTAINS
       size: 60
@@ -29,6 +31,7 @@ content:
   created:
     type: datetime_timestamp
     weight: 10
+    region: content
     settings: {  }
     third_party_settings: {  }
   promote:
@@ -36,16 +39,19 @@ content:
     settings:
       display_label: true
     weight: 15
+    region: content
     third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
       display_label: true
     weight: 16
+    region: content
     third_party_settings: {  }
   body:
     type: text_textarea_with_summary
     weight: 26
+    region: content
     settings:
       rows: 9
       summary_rows: 3
diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml
index c107b10..aaea1cb 100644
--- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml
+++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml
@@ -14,10 +14,12 @@ mode: default
 content:
   links:
     weight: 100
+    region: content
   body:
     label: hidden
     type: text_default
     weight: 101
+    region: content
     settings: {  }
     third_party_settings: {  }
 hidden:
diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml
index 3b472a7..6e79af9 100644
--- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml
+++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml
@@ -15,10 +15,12 @@ mode: teaser
 content:
   links:
     weight: 100
+    region: content
   body:
     label: hidden
     type: text_summary_or_trimmed
     weight: 101
+    region: content
     settings:
       trim_length: 600
     third_party_settings: {  }
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 154a55b..f732299 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1680,3 +1680,18 @@ function system_update_8200(&$sandbox) {
   $sandbox['config_names'] = array_diff($sandbox['config_names'], $config_names_to_process);
   $sandbox['#finished'] = empty($sandbox['config_names']) ? 1 : ($sandbox['max'] - count($sandbox['config_names'])) / $sandbox['max'];
 }
+
+/**
+ * Update entity displays to contain the region for each field.
+ */
+function system_update_8201() {
+  $config_factory = \Drupal::configFactory();
+  $config_names = array_merge($config_factory->listAll('core.entity_view_display.'), $config_factory->listAll('core.entity_form_display.'));
+  foreach ($config_names as $name) {
+    $config = $config_factory->getEditable($name);
+    foreach ($config->get('content') as $name => $field) {
+      $config->set('content.' . $name . '.region', 'content');
+    }
+    $config->save(TRUE);
+  }
+}
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 030b9a9..d25f7b2 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -435,7 +435,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
 
     $fields['langcode']->setLabel(t('Language code'))
       ->setDescription(t('The user language code.'))
-      ->setDisplayOptions('form', ['type' => 'hidden']);
+      ->setDisplayOptions('form', ['region' => 'hidden']);
 
     $fields['preferred_langcode'] = BaseFieldDefinition::create('language')
       ->setLabel(t('Preferred language code'))
diff --git a/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml b/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml
index ee0c138..7ccb5b0 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml
@@ -14,6 +14,7 @@ content:
   body:
     type: text_textarea_with_summary
     weight: -4
+    region: content
     settings:
       rows: 9
       summary_rows: 3
@@ -22,6 +23,7 @@ content:
   info:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
diff --git a/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml b/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml
index fa5d834..1010be2 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml
@@ -13,9 +13,11 @@ mode: default
 content:
   author:
     weight: -2
+    region: content
   comment_body:
     type: text_textarea
     weight: 11
+    region: content
     settings:
       rows: 5
       placeholder: ''
@@ -23,6 +25,7 @@ content:
   subject:
     type: string_textfield
     weight: 10
+    region: content
     settings:
       size: 60
       placeholder: ''
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
index 79156b2..c94e36e 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
@@ -21,6 +21,7 @@ content:
   body:
     type: text_textarea_with_summary
     weight: 1
+    region: content
     settings:
       rows: 9
       summary_rows: 3
@@ -29,16 +30,19 @@ content:
   comment:
     type: comment_default
     weight: 20
+    region: content
     settings: {  }
     third_party_settings: {  }
   created:
     type: datetime_timestamp
     weight: 10
+    region: content
     settings: {  }
     third_party_settings: {  }
   field_image:
     type: image_image
     weight: 4
+    region: content
     settings:
       progress_indicator: throbber
       preview_image_style: thumbnail
@@ -46,11 +50,13 @@ content:
   field_tags:
     type: entity_reference_autocomplete_tags
     weight: 3
+    region: content
     settings: {  }
     third_party_settings: {  }
   path:
     type: path
     weight: 30
+    region: content
     settings: {  }
     third_party_settings: {  }
   promote:
@@ -58,16 +64,19 @@ content:
     settings:
       display_label: true
     weight: 15
+    region: content
     third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
       display_label: true
     weight: 16
+    region: content
     third_party_settings: {  }
   title:
     type: string_textfield
     weight: 0
+    region: content
     settings:
       size: 60
       placeholder: ''
@@ -75,6 +84,7 @@ content:
   uid:
     type: entity_reference_autocomplete
     weight: 5
+    region: content
     settings:
       match_operator: CONTAINS
       size: 60
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
index 1fef06d..0b7ffd1 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
@@ -15,6 +15,7 @@ content:
   body:
     type: text_textarea_with_summary
     weight: 31
+    region: content
     settings:
       rows: 9
       summary_rows: 3
@@ -23,11 +24,13 @@ content:
   created:
     type: datetime_timestamp
     weight: 10
+    region: content
     settings: {  }
     third_party_settings: {  }
   path:
     type: path
     weight: 30
+    region: content
     settings: {  }
     third_party_settings: {  }
   promote:
@@ -35,16 +38,19 @@ content:
     settings:
       display_label: true
     weight: 15
+    region: content
     third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
       display_label: true
     weight: 16
+    region: content
     third_party_settings: {  }
   title:
     type: string_textfield
     weight: -5
+    region: content
     settings:
       size: 60
       placeholder: ''
@@ -52,6 +58,7 @@ content:
   uid:
     type: entity_reference_autocomplete
     weight: 5
+    region: content
     settings:
       match_operator: CONTAINS
       size: 60
diff --git a/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml b/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml
index 466b6e0..6832229 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml
@@ -14,12 +14,16 @@ mode: default
 content:
   account:
     weight: -10
+    region: content
   contact:
     weight: 5
+    region: content
   language:
     weight: 0
+    region: content
   timezone:
     weight: 6
+    region: content
   user_picture:
     type: image_image
     settings:
@@ -27,4 +31,5 @@ content:
       preview_image_style: thumbnail
     third_party_settings: {  }
     weight: -1
+    region: content
 hidden: {  }
diff --git a/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml b/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml
index bd52f77..e494882 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml
@@ -15,6 +15,7 @@ content:
     label: hidden
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
 hidden: {  }
diff --git a/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml b/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml
index 1ed49ce..6ae213d 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml
@@ -15,8 +15,10 @@ content:
     label: hidden
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
   links:
     weight: 100
+    region: content
 hidden: {  }
diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml
index 98a2de8..5c43252 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml
@@ -22,12 +22,14 @@ content:
   body:
     type: text_default
     weight: 0
+    region: content
     settings: {  }
     third_party_settings: {  }
     label: hidden
   comment:
     type: comment_default
     weight: 110
+    region: content
     label: above
     settings:
       view_mode: default
@@ -36,6 +38,7 @@ content:
   field_image:
     type: image
     weight: -1
+    region: content
     settings:
       image_style: large
       image_link: ''
@@ -44,12 +47,14 @@ content:
   field_tags:
     type: entity_reference_label
     weight: 10
+    region: content
     label: above
     settings:
       link: true
     third_party_settings: {  }
   links:
     weight: 100
+    region: content
 hidden:
   field_image: true
   field_tags: true
diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml
index 75a14a3..84660b6 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml
@@ -17,6 +17,7 @@ mode: rss
 content:
   links:
     weight: 100
+    region: content
 hidden:
   body: true
   comment: true
diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml
index 43ee079..7b96908 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml
@@ -21,6 +21,7 @@ content:
   body:
     type: text_summary_or_trimmed
     weight: 0
+    region: content
     settings:
       trim_length: 600
     third_party_settings: {  }
@@ -28,6 +29,7 @@ content:
   field_image:
     type: image
     weight: -1
+    region: content
     settings:
       image_style: medium
       image_link: content
@@ -36,12 +38,14 @@ content:
   field_tags:
     type: entity_reference_label
     weight: 10
+    region: content
     settings:
       link: true
     third_party_settings: {  }
     label: above
   links:
     weight: 100
+    region: content
 hidden:
   comment: true
   field_image: true
diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml
index dcb2d3e..8afd942 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml
@@ -16,8 +16,10 @@ content:
     label: hidden
     type: text_default
     weight: 100
+    region: content
     settings: {  }
     third_party_settings: {  }
   links:
     weight: 101
+    region: content
 hidden: {  }
diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml b/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml
index f235a10..bc7a68c 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml
@@ -17,9 +17,11 @@ content:
     label: hidden
     type: text_summary_or_trimmed
     weight: 100
+    region: content
     settings:
       trim_length: 600
     third_party_settings: {  }
   links:
     weight: 101
+    region: content
 hidden: {  }
diff --git a/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml b/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml
index 4c13792..2ff13ad 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml
@@ -16,6 +16,7 @@ content:
   user_picture:
     type: image
     weight: 0
+    region: content
     settings:
       image_style: thumbnail
       image_link: content
diff --git a/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml b/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml
index 9e4621d..ef1fdd7 100644
--- a/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml
+++ b/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml
@@ -14,9 +14,11 @@ mode: default
 content:
   member_for:
     weight: 5
+    region: content
   user_picture:
     type: image
     weight: 0
+    region: content
     settings:
       image_style: thumbnail
       image_link: content
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php
new file mode 100644
index 0000000..c128365
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Entity;
+
+use Drupal\Core\Entity\Display\EntityDisplayInterface;
+use Drupal\Core\Form\FormState;
+use Drupal\field_ui\Form\EntityViewDisplayEditForm;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\field_ui\Form\EntityDisplayFormBase
+ *
+ * @group Entity
+ */
+class EntityDisplayFormBaseTest extends KernelTestBase {
+
+  /**
+   * @covers ::determineComponentAction
+   */
+  public function testDetermineComponentAction() {
+    $entity = $this->prophesize(EntityDisplayInterface::class);
+    $entity->getPluginCollections()->willReturn([]);
+    $entity->getComponent('field_hidden_no_changes')->willReturn([
+      'weight' => 0,
+      'type' => 'hidden',
+      'region' => 'hidden',
+    ]);
+    $entity->removeComponent('field_hidden_no_changes')->shouldBeCalled();
+    $entity->getComponent('field_visible_no_changes')->willReturn([
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ]);
+    $entity->setComponent('field_visible_no_changes', [
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ])->shouldBeCalled();
+    $entity->getComponent('field_start_hidden_change_type')->willReturn([
+      'weight' => 0,
+      'type' => 'hidden',
+      'region' => 'hidden',
+    ]);
+    $entity->setComponent('field_start_hidden_change_type', [
+      'weight' => 0,
+      'type' => 'textfield',
+    ])->shouldBeCalled();
+    $entity->getComponent('field_start_hidden_change_region')->willReturn([
+      'weight' => 0,
+      'type' => 'hidden',
+      'region' => 'hidden',
+    ]);
+    $entity->setComponent('field_start_hidden_change_region', [
+      'weight' => 0,
+      'region' => 'content',
+    ])->shouldBeCalled();
+    $entity->getComponent('field_start_hidden_change_both')->willReturn([
+      'weight' => 0,
+      'type' => 'hidden',
+      'region' => 'hidden',
+    ]);
+    $entity->setComponent('field_start_hidden_change_both', [
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ])->shouldBeCalled();
+    $entity->getComponent('field_start_visible_change_type')->willReturn([
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ]);
+    $entity->removeComponent('field_start_visible_change_type')->shouldBeCalled();
+    $entity->getComponent('field_start_visible_change_region')->willReturn([
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ]);
+    $entity->removeComponent('field_start_visible_change_region')->shouldBeCalled();
+    $entity->getComponent('field_start_visible_change_both')->willReturn([
+      'weight' => 0,
+      'type' => 'textfield',
+      'region' => 'content',
+    ]);
+    $entity->removeComponent('field_start_visible_change_both')->shouldBeCalled();
+    $entity->save()->shouldBeCalled();
+
+    $fields = [
+      'field_hidden_no_changes' => [
+        'weight' => 0,
+        'type' => 'hidden',
+        'region' => 'hidden',
+      ],
+      'field_visible_no_changes' => [
+        'weight' => 0,
+        'type' => 'textfield',
+        'region' => 'content',
+      ],
+      'field_start_hidden_change_type' => [
+        'weight' => 0,
+        'type' => 'textfield',
+        'region' => 'hidden',
+      ],
+      'field_start_hidden_change_region' => [
+        'weight' => 0,
+        'type' => 'hidden',
+        'region' => 'content',
+      ],
+      'field_start_hidden_change_both' => [
+        'weight' => 0,
+        'type' => 'textfield',
+        'region' => 'content',
+      ],
+      'field_start_visible_change_type' => [
+        'weight' => 0,
+        'type' => 'hidden',
+        'region' => 'content',
+      ],
+      'field_start_visible_change_region' => [
+        'weight' => 0,
+        'type' => 'textfield',
+        'region' => 'hidden',
+      ],
+      'field_start_visible_change_both' => [
+        'weight' => 0,
+        'type' => 'hidden',
+        'region' => 'hidden',
+      ],
+    ];
+
+    $form = [
+      '#fields' => array_keys($fields),
+      '#extra' => [],
+    ];
+    $form_state = (new FormState())->setFormState(['values' => ['fields' => $fields]]);
+
+    $form_object = new EntityViewDisplayEditForm($this->container->get('plugin.manager.field.field_type'), $this->container->get('plugin.manager.field.formatter'));
+    $form_object->setEntity($entity->reveal());
+    $form_object->buildEntity($form, $form_state);
+    $form_object->save($form, $form_state);
+    $form_object->buildEntity($form, $form_state);
+  }
+
+}
