diff --git a/core/modules/layout_builder/config/schema/layout_builder.schema.yml b/core/modules/layout_builder/config/schema/layout_builder.schema.yml
index 3b584529..4c039a33 100644
--- a/core/modules/layout_builder/config/schema/layout_builder.schema.yml
+++ b/core/modules/layout_builder/config/schema/layout_builder.schema.yml
@@ -71,6 +71,12 @@ inline_block:
     block_serialized:
       type: string
       label: 'Serialized block'
+    type:
+      type: string
+      label: 'Block type'
+    uuid:
+      type: string
+      label: 'Block UUID'
 
 block.settings.inline_block:*:
   type: inline_block
diff --git a/core/modules/layout_builder/config/schema/layout_builder.schema.yml.orig b/core/modules/layout_builder/config/schema/layout_builder.schema.yml.orig
new file mode 100644
index 00000000..3b584529
--- /dev/null
+++ b/core/modules/layout_builder/config/schema/layout_builder.schema.yml.orig
@@ -0,0 +1,89 @@
+core.entity_view_display.*.*.*.third_party.layout_builder:
+  type: mapping
+  label: 'Per-view-mode Layout Builder settings'
+  mapping:
+    enabled:
+      type: boolean
+      label: 'Whether the Layout Builder is enabled for this display'
+    allow_custom:
+      type: boolean
+      label: 'Allow a customized layout'
+    sections:
+      type: sequence
+      sequence:
+        type: layout_builder.section
+
+layout_builder.section:
+  type: mapping
+  label: 'Layout section'
+  mapping:
+    layout_id:
+      type: string
+      label: 'Layout ID'
+    layout_settings:
+      type: layout_plugin.settings.[%parent.layout_id]
+      label: 'Layout settings'
+    components:
+      type: sequence
+      label: 'Components'
+      sequence:
+        type: layout_builder.component
+    third_party_settings:
+      type: sequence
+      label: 'Third party settings'
+      sequence:
+        type: '[%parent.%parent.%type].third_party.[%key]'
+
+layout_builder.component:
+  type: mapping
+  label: 'Component'
+  mapping:
+    configuration:
+      type: block.settings.[id]
+    region:
+      type: string
+      label: 'Region'
+    uuid:
+      type: uuid
+      label: 'UUID'
+    weight:
+      type: integer
+      label: 'Weight'
+    additional:
+      type: ignore
+      label: 'Additional data'
+    third_party_settings:
+      type: sequence
+      label: 'Third party settings'
+      sequence:
+        type: ignore
+
+inline_block:
+  type: block_settings
+  label: 'Inline block'
+  mapping:
+    view_mode:
+      type: string
+      label: 'View mode'
+    block_revision_id:
+      type: integer
+      label: 'Block revision ID'
+    block_serialized:
+      type: string
+      label: 'Serialized block'
+
+block.settings.inline_block:*:
+  type: inline_block
+
+layout_builder_multi_width:
+  type: layout_plugin.settings
+  mapping:
+    column_widths:
+      type: string
+      label: 'Column widths'
+
+layout_plugin.settings.layout_twocol_section:
+  type: layout_builder_multi_width
+
+layout_plugin.settings.layout_threecol_section:
+  type: layout_builder_multi_width
diff --git a/core/modules/layout_builder/layout_builder.services.yml b/core/modules/layout_builder/layout_builder.services.yml
index b2ee1fe1..7afec92b 100644
--- a/core/modules/layout_builder/layout_builder.services.yml
+++ b/core/modules/layout_builder/layout_builder.services.yml
@@ -58,3 +58,14 @@ services:
     class: Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController
     public: false
     arguments: ['@layout_builder.controller.entity_form.inner']
+  layout_builder.normalizer.entity_display:
+    class: Drupal\layout_builder\Normalizer\LayoutEntityDisplayNormalizer
+    arguments: ['@entity_type.manager', '@entity_type.repository', '@entity_field.manager']
+    tags:
+    # Priority must be higher than serializer.normalizer.config_entity.
+      - { name: normalizer, priority: 1 }
+  layout_builder.normalizer.section_data:
+    class: Drupal\layout_builder\Normalizer\SectionDataNormalizer
+    tags:
+    # Priority must be higher than serializer.normalizer.typed_data.
+      - { name: normalizer, priority: 1 }
diff --git a/core/modules/layout_builder/src/Field/LayoutSectionItemList.php b/core/modules/layout_builder/src/Field/LayoutSectionItemList.php
index 3243be97..3721cedf 100644
--- a/core/modules/layout_builder/src/Field/LayoutSectionItemList.php
+++ b/core/modules/layout_builder/src/Field/LayoutSectionItemList.php
@@ -102,6 +102,11 @@ public function equals(FieldItemListInterface $list_to_compare) {
    */
   public function defaultAccess($operation = 'view', AccountInterface $account = NULL) {
     // @todo Allow access in https://www.drupal.org/node/2942975.
+
+    if ($operation === 'view') {
+      return parent::defaultAccess($operation, $account);
+    }
+
     return AccessResult::forbidden();
   }
 
diff --git a/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php b/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php
index 39e02173..f9eaecaa 100644
--- a/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php
+++ b/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php
@@ -5,7 +5,6 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency;
-use Drupal\layout_builder\Normalizer\LayoutEntityDisplayNormalizer;
 use Symfony\Component\DependencyInjection\ChildDefinition;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\Reference;
@@ -40,14 +39,6 @@ public function register(ContainerBuilder $container) {
       $definition->addTag('event_subscriber');
       $container->setDefinition('layout_builder.get_block_dependency_subscriber', $definition);
     }
-    if (isset($modules['serialization'])) {
-      $definition = (new ChildDefinition('serializer.normalizer.config_entity'))
-        ->setClass(LayoutEntityDisplayNormalizer::class)
-        // Ensure that this normalizer takes precedence for Layout Builder data
-        // over the generic serializer.normalizer.config_entity.
-        ->addTag('normalizer', ['priority' => 5]);
-      $container->setDefinition('layout_builder.normalizer.layout_entity_display', $definition);
-    }
   }
 
 }
diff --git a/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php.orig b/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php.orig
new file mode 100644
index 00000000..39e02173
--- /dev/null
+++ b/core/modules/layout_builder/src/LayoutBuilderServiceProvider.php.orig
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\layout_builder;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\DependencyInjection\ServiceProviderInterface;
+use Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency;
+use Drupal\layout_builder\Normalizer\LayoutEntityDisplayNormalizer;
+use Symfony\Component\DependencyInjection\ChildDefinition;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Sets the layout_builder.get_block_dependency_subscriber service definition.
+ *
+ * This service is dependent on the block_content module so it must be provided
+ * dynamically.
+ *
+ * @internal
+ *   Service providers are internal.
+ *
+ * @see \Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency
+ */
+class LayoutBuilderServiceProvider implements ServiceProviderInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function register(ContainerBuilder $container) {
+    $modules = $container->getParameter('container.modules');
+    if (isset($modules['block_content'])) {
+      $definition = new Definition(SetInlineBlockDependency::class);
+      $definition->setArguments([
+        new Reference('entity.repository'),
+        new Reference('database'),
+        new Reference('inline_block.usage'),
+        new Reference('plugin.manager.layout_builder.section_storage'),
+        new Reference('current_route_match')
+      ]);
+      $definition->addTag('event_subscriber');
+      $container->setDefinition('layout_builder.get_block_dependency_subscriber', $definition);
+    }
+    if (isset($modules['serialization'])) {
+      $definition = (new ChildDefinition('serializer.normalizer.config_entity'))
+        ->setClass(LayoutEntityDisplayNormalizer::class)
+        // Ensure that this normalizer takes precedence for Layout Builder data
+        // over the generic serializer.normalizer.config_entity.
+        ->addTag('normalizer', ['priority' => 5]);
+      $container->setDefinition('layout_builder.normalizer.layout_entity_display', $definition);
+    }
+  }
+
+}
diff --git a/core/modules/layout_builder/src/Normalizer/LayoutEntityDisplayNormalizer.php b/core/modules/layout_builder/src/Normalizer/LayoutEntityDisplayNormalizer.php
index 886304fa..9d54bb61 100644
--- a/core/modules/layout_builder/src/Normalizer/LayoutEntityDisplayNormalizer.php
+++ b/core/modules/layout_builder/src/Normalizer/LayoutEntityDisplayNormalizer.php
@@ -4,6 +4,7 @@
 
 use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
 use Drupal\serialization\Normalizer\ConfigEntityNormalizer;
+use Drupal\layout_builder\Section;
 
 /**
  * Normalizes/denormalizes LayoutEntityDisplay objects into an array structure.
@@ -21,13 +22,26 @@ class LayoutEntityDisplayNormalizer extends ConfigEntityNormalizer {
   /**
    * {@inheritdoc}
    */
-  protected static function getDataWithoutInternals(array $data) {
-    $data = parent::getDataWithoutInternals($data);
-    // Do not expose the actual layout sections in normalization.
-    // @todo Determine what to expose here in
-    //   https://www.drupal.org/node/2942975.
-    unset($data['third_party_settings']['layout_builder']['sections']);
+  public function normalize($object, $format = NULL, array $context = []) {
+    $data = static::getDataWithoutInternals($object->toArray());
+    if (!empty($data['third_party_settings']['layout_builder']['sections'])) {
+      $sections = &$data['third_party_settings']['layout_builder']['sections'];
+      $sections = array_map(static function (Section $section) {
+        return $section->toArray();
+      }, $sections);
+    }
     return $data;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function denormalize($data, $class, $format = NULL, array $context = []) {
+    if (!empty($data['third_party_settings']['layout_builder']['sections'])) {
+      $sections = &$data['third_party_settings']['layout_builder']['sections'];
+      $sections = array_map([Section::class, 'fromArray'], $sections);
+    }
+    return parent::denormalize(static::getDataWithoutInternals($data), $class, $format, $context);
+  }
+
 }
diff --git a/core/modules/layout_builder/src/Normalizer/SectionDataNormalizer.php b/core/modules/layout_builder/src/Normalizer/SectionDataNormalizer.php
new file mode 100644
index 00000000..761c2b12
--- /dev/null
+++ b/core/modules/layout_builder/src/Normalizer/SectionDataNormalizer.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\layout_builder\Normalizer;
+
+use Drupal\layout_builder\Section;
+use Drupal\layout_builder\Plugin\DataType\SectionData;
+use Drupal\serialization\Normalizer\TypedDataNormalizer;
+use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
+
+/**
+ * Normalizes section data.
+ */
+class SectionDataNormalizer extends TypedDataNormalizer implements DenormalizerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $supportedInterfaceOrClass = SectionData::class;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function normalize($object, $format = NULL, array $context = []) {
+    return $object->getValue()->toArray();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function denormalize($data, $class, $format = NULL, array $context = []) {
+    return Section::fromArray($data);
+  }
+
+}
diff --git a/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php b/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php
index 027a2f70..c9f6bd77 100644
--- a/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php
+++ b/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php
@@ -261,6 +261,10 @@ protected function getEntity() {
           'reusable' => FALSE,
         ]);
       }
+      if (isset($this->configuration['type']) && isset($this->configuration['uuid'])) {
+        $entity = $this->entityTypeManager->getStorage('block_content')->loadByProperties(['uuid' => $this->configuration['uuid']]);
+        $this->blockContent = is_array($entity) ? array_pop($entity) : $entity;
+      }
       if ($this->blockContent instanceof RefinableDependentAccessInterface && $dependee = $this->getAccessDependency()) {
         $this->blockContent->setAccessDependency($dependee);
       }
@@ -311,6 +315,8 @@ public function saveBlockContent($new_revision = FALSE, $duplicate_block = FALSE
       $block->save();
       $this->configuration['block_revision_id'] = $block->getRevisionId();
       $this->configuration['block_serialized'] = NULL;
+      $this->configuration['type'] = $block->bundle();
+      $this->configuration['uuid'] = $block->uuid();
     }
   }
 
diff --git a/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php.orig b/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php.orig
new file mode 100644
index 00000000..027a2f70
--- /dev/null
+++ b/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php.orig
@@ -0,0 +1,317 @@
+<?php
+
+namespace Drupal\layout_builder\Plugin\Block;
+
+use Drupal\block_content\Access\RefinableDependentAccessInterface;
+use Drupal\block_content\Access\RefinableDependentAccessTrait;
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\SubformStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Defines an inline block plugin type.
+ *
+ * @Block(
+ *  id = "inline_block",
+ *  admin_label = @Translation("Inline block"),
+ *  category = @Translation("Inline blocks"),
+ *  deriver = "Drupal\layout_builder\Plugin\Derivative\InlineBlockDeriver",
+ * )
+ *
+ * @internal
+ *   Plugin classes are internal.
+ */
+class InlineBlock extends BlockBase implements ContainerFactoryPluginInterface, RefinableDependentAccessInterface {
+
+  use RefinableDependentAccessTrait;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The block content entity.
+   *
+   * @var \Drupal\block_content\BlockContentInterface
+   */
+  protected $blockContent;
+
+  /**
+   * The entity display repository.
+   *
+   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
+   */
+  protected $entityDisplayRepository;
+
+  /**
+   * Whether a new block is being created.
+   *
+   * @var bool
+   */
+  protected $isNew = TRUE;
+
+  /**
+   * The time.
+   *
+   * @var \Drupal\Component\Datetime\TimeInterface
+   */
+  protected $time;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Constructs a new InlineBlock.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager service.
+   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
+   *   The entity display repository.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository, TimeInterface $time, AccountInterface $current_user = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityDisplayRepository = $entity_display_repository;
+    $this->time = $time;
+
+    if (!empty($this->configuration['block_revision_id']) || !empty($this->configuration['block_serialized'])) {
+      $this->isNew = FALSE;
+    }
+
+    if (!$current_user) {
+      @trigger_error('The current_user service must be passed to InlineBlock::__construct(), it is required before Drupal 9.0.0.', E_USER_DEPRECATED);
+      $current_user = \Drupal::currentUser();
+    }
+    $this->currentUser = $current_user;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager'),
+      $container->get('entity_display.repository'),
+      $container->get('datetime.time'),
+      $container->get('current_user')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'view_mode' => 'full',
+      'block_revision_id' => NULL,
+      'block_serialized' => NULL,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockForm($form, FormStateInterface $form_state) {
+    $block = $this->getEntity();
+
+    // Add the entity form display in a process callback so that #parents can
+    // be successfully propagated to field widgets.
+    $form['block_form'] = [
+      '#type' => 'container',
+      '#process' => [[static::class, 'processBlockForm']],
+      '#block' => $block,
+      '#access' => $this->currentUser->hasPermission('create and edit custom blocks'),
+    ];
+
+    $options = $this->entityDisplayRepository->getViewModeOptionsByBundle('block_content', $block->bundle());
+
+    $form['view_mode'] = [
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => $this->t('View mode'),
+      '#description' => $this->t('The view mode in which to render the block.'),
+      '#default_value' => $this->configuration['view_mode'],
+      '#access' => count($options) > 1,
+    ];
+    return $form;
+  }
+
+  /**
+   * Process callback to insert a Custom Block form.
+   *
+   * @param array $element
+   *   The containing element.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   *
+   * @return array
+   *   The containing element, with the Custom Block form inserted.
+   */
+  public static function processBlockForm(array $element, FormStateInterface $form_state) {
+    /** @var \Drupal\block_content\BlockContentInterface $block */
+    $block = $element['#block'];
+    EntityFormDisplay::collectRenderDisplay($block, 'edit')->buildForm($block, $element, $form_state);
+    $element['revision_log']['#access'] = FALSE;
+    $element['info']['#access'] = FALSE;
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockValidate($form, FormStateInterface $form_state) {
+    $block_form = $form['block_form'];
+    /** @var \Drupal\block_content\BlockContentInterface $block */
+    $block = $block_form['#block'];
+    // Set changed time if update block content.
+    // it will trigger \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraintValidator::validate()
+    if (!$this->isNew && $block instanceof EntityChangedInterface) {
+      $block->setChangedTime($this->time->getCurrentTime());
+    }
+    $form_display = EntityFormDisplay::collectRenderDisplay($block, 'edit');
+    $complete_form_state = $form_state instanceof SubformStateInterface ? $form_state->getCompleteFormState() : $form_state;
+    $form_display->extractFormValues($block, $block_form, $complete_form_state);
+    $form_display->validateFormValues($block, $block_form, $complete_form_state);
+    // @todo Remove when https://www.drupal.org/project/drupal/issues/2948549 is closed.
+    $form_state->setTemporaryValue('block_form_parents', $block_form['#parents']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockSubmit($form, FormStateInterface $form_state) {
+    $this->configuration['view_mode'] = $form_state->getValue('view_mode');
+
+    // @todo Remove when https://www.drupal.org/project/drupal/issues/2948549 is closed.
+    $block_form = NestedArray::getValue($form, $form_state->getTemporaryValue('block_form_parents'));
+    /** @var \Drupal\block_content\BlockContentInterface $block */
+    $block = $block_form['#block'];
+    $form_display = EntityFormDisplay::collectRenderDisplay($block, 'edit');
+    $complete_form_state = $form_state instanceof SubformStateInterface ? $form_state->getCompleteFormState() : $form_state;
+    $form_display->extractFormValues($block, $block_form, $complete_form_state);
+    $block->setInfo($this->configuration['label']);
+    $this->configuration['block_serialized'] = serialize($block);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function blockAccess(AccountInterface $account) {
+    if ($entity = $this->getEntity()) {
+      return $entity->access('view', $account, TRUE);
+    }
+    return AccessResult::forbidden();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    $block = $this->getEntity();
+    return $this->entityTypeManager->getViewBuilder($block->getEntityTypeId())->view($block, $this->configuration['view_mode']);
+  }
+
+  /**
+   * Loads or creates the block content entity of the block.
+   *
+   * @return \Drupal\block_content\BlockContentInterface
+   *   The block content entity.
+   */
+  protected function getEntity() {
+    if (!isset($this->blockContent)) {
+      if (!empty($this->configuration['block_serialized'])) {
+        $this->blockContent = unserialize($this->configuration['block_serialized']);
+      }
+      elseif (!empty($this->configuration['block_revision_id'])) {
+        $entity = $this->entityTypeManager->getStorage('block_content')->loadRevision($this->configuration['block_revision_id']);
+        $this->blockContent = $entity;
+      }
+      else {
+        $this->blockContent = $this->entityTypeManager->getStorage('block_content')->create([
+          'type' => $this->getDerivativeId(),
+          'reusable' => FALSE,
+        ]);
+      }
+      if ($this->blockContent instanceof RefinableDependentAccessInterface && $dependee = $this->getAccessDependency()) {
+        $this->blockContent->setAccessDependency($dependee);
+      }
+    }
+    return $this->blockContent;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+    if ($this->isNew) {
+      // If the Content Block is new then don't provide a default label.
+      unset($form['label']['#default_value']);
+    }
+    $form['label']['#description'] = $this->t('The title of the block as shown to the user.');
+    return $form;
+  }
+
+  /**
+   * Saves the block_content entity for this plugin.
+   *
+   * @param bool $new_revision
+   *   Whether to create new revision.
+   * @param bool $duplicate_block
+   *   Whether to duplicate the "block_content" entity.
+   */
+  public function saveBlockContent($new_revision = FALSE, $duplicate_block = FALSE) {
+    /** @var \Drupal\block_content\BlockContentInterface $block */
+    $block = NULL;
+    if (!empty($this->configuration['block_serialized'])) {
+      $block = unserialize($this->configuration['block_serialized']);
+    }
+    if ($duplicate_block) {
+      if (empty($block) && !empty($this->configuration['block_revision_id'])) {
+        $block = $this->entityTypeManager->getStorage('block_content')->loadRevision($this->configuration['block_revision_id']);
+      }
+      if ($block) {
+        $block = $block->createDuplicate();
+      }
+    }
+
+    if ($block) {
+      if ($new_revision) {
+        $block->setNewRevision();
+      }
+      $block->save();
+      $this->configuration['block_revision_id'] = $block->getRevisionId();
+      $this->configuration['block_serialized'] = NULL;
+    }
+  }
+
+}
diff --git a/core/modules/layout_builder/src/Plugin/DataType/SectionData.php b/core/modules/layout_builder/src/Plugin/DataType/SectionData.php
index 8783904d..c59d77fa 100644
--- a/core/modules/layout_builder/src/Plugin/DataType/SectionData.php
+++ b/core/modules/layout_builder/src/Plugin/DataType/SectionData.php
@@ -30,8 +30,17 @@ class SectionData extends TypedData {
    * {@inheritdoc}
    */
   public function setValue($value, $notify = TRUE) {
+    if ($value && is_array($value)) {
+      $value = Section::fromArray($value);
+    }
+
     if ($value && !$value instanceof Section) {
-      throw new \InvalidArgumentException(sprintf('Value assigned to "%s" is not a valid section', $this->getName()));
+      if (isset($value->value) && !$value->value instanceof Section) {
+        throw new \InvalidArgumentException(sprintf('Value assigned to "%s" is not a valid section', $this->getName()));
+      }
+      else {
+        parent::setValue($value->value, $notify);
+      }
     }
     parent::setValue($value, $notify);
   }
diff --git a/core/modules/layout_builder/src/Section.php b/core/modules/layout_builder/src/Section.php
index 41fe13c5..776068cd 100644
--- a/core/modules/layout_builder/src/Section.php
+++ b/core/modules/layout_builder/src/Section.php
@@ -337,9 +337,9 @@ public function toArray() {
     return [
       'layout_id' => $this->getLayoutId(),
       'layout_settings' => $this->getLayoutSettings(),
-      'components' => array_map(function (SectionComponent $component) {
+      'components' => array_values(array_map(function (SectionComponent $component) {
         return $component->toArray();
-      }, $this->getComponents()),
+        }, $this->getComponents())),
       'third_party_settings' => $this->thirdPartySettings,
     ];
   }
