diff --git a/core/lib/Drupal/Core/Plugin/Context/EntityContext.php b/core/lib/Drupal/Core/Plugin/Context/EntityContext.php
index 131360df26..00ea81f759 100644
--- a/core/lib/Drupal/Core/Plugin/Context/EntityContext.php
+++ b/core/lib/Drupal/Core/Plugin/Context/EntityContext.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Plugin\Context;
 
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 
@@ -10,6 +11,8 @@
  */
 class EntityContext extends Context {
 
+  use DependencySerializationTrait;
+
   /**
    * Gets a context from an entity type ID.
    *
diff --git a/core/modules/layout_builder/layout_builder.module b/core/modules/layout_builder/layout_builder.module
index 5d7c60615c..0676365f70 100644
--- a/core/modules/layout_builder/layout_builder.module
+++ b/core/modules/layout_builder/layout_builder.module
@@ -202,3 +202,12 @@ function layout_builder_block_content_access(EntityInterface $entity, $operation
   }
   return AccessResult::forbidden();
 }
+
+/**
+ * Implements hook_layout_builder_section_storage_alter().
+ */
+function layout_builder_layout_builder_section_storage_alter(array &$definitions) {
+  /** @var \Drupal\layout_builder\SectionStorage\SectionStorageDefinition[] $definitions */
+  $definitions['overrides']->getContextDefinition('entity')
+    ->addConstraint('EntityHasField', 'layout_builder__layout');
+}
diff --git a/core/modules/layout_builder/src/Annotation/SectionStorage.php b/core/modules/layout_builder/src/Annotation/SectionStorage.php
index 42f4a47fe6..73924be8ad 100644
--- a/core/modules/layout_builder/src/Annotation/SectionStorage.php
+++ b/core/modules/layout_builder/src/Annotation/SectionStorage.php
@@ -22,6 +22,30 @@ class SectionStorage extends Plugin {
    */
   public $id;
 
+  /**
+   * The plugin weight, optional (defaults to 0).
+   *
+   * When an entity with layout is rendered, section storage plugins are
+   * checked, in order of their weight, to determine which one should be used
+   * to render the layout.
+   *
+   * @var int
+   */
+  public $weight = 0;
+
+  /**
+   * Any required context definitions, optional.
+   *
+   * When an entity with layout is rendered, all section storage plugins which
+   * match a particular set of contexts are checked, in order of their weight,
+   * to determine which plugin should be used to render the layout.
+   *
+   * @var array
+   *
+   * @see \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::getRuntimeSections()
+   */
+  public $context = [];
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php b/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php
index 2bdeb03870..d91d08575d 100644
--- a/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php
+++ b/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php
@@ -9,6 +9,7 @@
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\layout_builder\LayoutEntityHelperTrait;
 use Drupal\layout_builder\Section;
 use Drupal\layout_builder\SectionComponent;
 use Drupal\layout_builder\SectionStorage\SectionStorageTrait;
@@ -23,6 +24,7 @@
  */
 class LayoutBuilderEntityViewDisplay extends BaseEntityViewDisplay implements LayoutEntityDisplayInterface {
 
+  use LayoutEntityHelperTrait;
   use SectionStorageTrait;
 
   /**
@@ -264,11 +266,15 @@ public function buildMultiple(array $entities) {
    *   The sections.
    */
   protected function getRuntimeSections(FieldableEntityInterface $entity) {
-    if ($this->isOverridable() && !$entity->get('layout_builder__layout')->isEmpty()) {
-      return $entity->get('layout_builder__layout')->getSections();
-    }
+    $sections = NULL;
 
-    return $this->getSections();
+    if ($this->isOverridable()) {
+      $sections = $this->getEntitySections($entity, $this->getMode());
+    }
+    // If we don't have a section list yet (i.e., no section storage plugin
+    // was able to derive a section list from context, or this display is not
+    // overridable), use this display as the section list.
+    return $sections ?: $this->getSections();
   }
 
   /**
diff --git a/core/modules/layout_builder/src/EventSubscriber/SetInlineBlockDependency.php b/core/modules/layout_builder/src/EventSubscriber/SetInlineBlockDependency.php
index edc05f83dd..4ea6259860 100644
--- a/core/modules/layout_builder/src/EventSubscriber/SetInlineBlockDependency.php
+++ b/core/modules/layout_builder/src/EventSubscriber/SetInlineBlockDependency.php
@@ -127,7 +127,8 @@ protected function getInlineBlockDependency(BlockContentInterface $block_content
     /** @var \Drupal\layout_builder\InlineBlockUsage $usage */
     $layout_entity_storage = $this->entityTypeManager->getStorage($layout_entity_info->layout_entity_type);
     $layout_entity = $layout_entity_storage->load($layout_entity_info->layout_entity_id);
-    if ($this->isLayoutCompatibleEntity($layout_entity)) {
+    // @todo Pass 'default' until resolving https://www.drupal.org/node/3008924.
+    if ($this->isLayoutCompatibleEntity($layout_entity, 'default')) {
       if ($this->isBlockRevisionUsedInEntity($layout_entity, $block_content)) {
         return $layout_entity;
       }
@@ -149,7 +150,8 @@ protected function getInlineBlockDependency(BlockContentInterface $block_content
    *   layout entity.
    */
   protected function isBlockRevisionUsedInEntity(EntityInterface $layout_entity, BlockContentInterface $block_content) {
-    $sections_blocks_revision_ids = $this->getInlineBlockRevisionIdsInSections($this->getEntitySections($layout_entity));
+    // @todo Pass 'default' until resolving https://www.drupal.org/node/3008924.
+    $sections_blocks_revision_ids = $this->getInlineBlockRevisionIdsInSections($this->getEntitySections($layout_entity, 'default'));
     return in_array($block_content->getRevisionId(), $sections_blocks_revision_ids);
   }
 
diff --git a/core/modules/layout_builder/src/InlineBlockEntityOperations.php b/core/modules/layout_builder/src/InlineBlockEntityOperations.php
index 7e64b83cf1..3469fca493 100644
--- a/core/modules/layout_builder/src/InlineBlockEntityOperations.php
+++ b/core/modules/layout_builder/src/InlineBlockEntityOperations.php
@@ -6,7 +6,9 @@
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Entity\RevisionableInterface;
+use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
 use Drupal\layout_builder\Plugin\Block\InlineBlock;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -85,10 +87,12 @@ protected function removeUnusedForEntityOnSave(EntityInterface $entity) {
     if ($entity->isNew() || !isset($entity->original) || $entity instanceof RevisionableInterface) {
       return;
     }
-    $sections = $this->getEntitySections($entity);
+    // @todo Use 'default' until resolving https://www.drupal.org/node/3008924.
+    $view_mode = 'default';
+    $sections = $this->getEntitySections($entity, $view_mode);
     // If this is a layout override and there are no sections then it is a new
     // override.
-    if ($this->isEntityUsingFieldOverride($entity) && empty($sections)) {
+    if ($this->isEntityUsingFieldOverride($entity, $view_mode) && empty($sections)) {
       return;
     }
 
@@ -108,8 +112,10 @@ protected function removeUnusedForEntityOnSave(EntityInterface $entity) {
    *   The block content IDs that were removed.
    */
   protected function getRemovedBlockIds(EntityInterface $entity) {
-    $original_sections = $this->getEntitySections($entity->original);
-    $current_sections = $this->getEntitySections($entity);
+    // @todo Use 'default' until resolving https://www.drupal.org/node/3008924.
+    $view_mode = 'default';
+    $original_sections = $this->getEntitySections($entity->original, $view_mode);
+    $current_sections = $this->getEntitySections($entity, $view_mode);
     // Avoid un-needed conversion from revision IDs to block content IDs by
     // first determining if there are any revisions in the original that are not
     // also in the current sections.
@@ -132,11 +138,28 @@ protected function getRemovedBlockIds(EntityInterface $entity) {
    *   The parent entity.
    */
   public function handleEntityDelete(EntityInterface $entity) {
-    if ($this->isLayoutCompatibleEntity($entity)) {
+    // @todo Pass 'default' until resolving https://www.drupal.org/node/3008924.
+    if ($this->isLayoutCompatibleEntity($entity, 'default')) {
       $this->usage->removeByLayoutEntity($entity);
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function isLayoutCompatibleEntity(EntityInterface $entity, $view_mode) {
+    // @todo Hardcode these checks to avoid https://www.drupal.org/node/3008943.
+    return $entity instanceof LayoutEntityDisplayInterface || $this->isEntityUsingFieldOverride($entity, $view_mode);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function isEntityUsingFieldOverride(EntityInterface $entity, $view_mode) {
+    // @todo Hardcode these checks to avoid https://www.drupal.org/node/3008943.
+    return $entity instanceof FieldableEntityInterface && $entity->hasField('layout_builder__layout');
+  }
+
   /**
    * Handles saving a parent entity.
    *
@@ -144,15 +167,17 @@ public function handleEntityDelete(EntityInterface $entity) {
    *   The parent entity.
    */
   public function handlePreSave(EntityInterface $entity) {
-    if (!$this->isLayoutCompatibleEntity($entity)) {
+    // @todo Use 'default' until resolving https://www.drupal.org/node/3008924.
+    $view_mode = 'default';
+    if (!$this->isLayoutCompatibleEntity($entity, $view_mode)) {
       return;
     }
     $duplicate_blocks = FALSE;
 
-    if ($sections = $this->getEntitySections($entity)) {
-      if ($this->isEntityUsingFieldOverride($entity)) {
+    if ($sections = $this->getEntitySections($entity, $view_mode)) {
+      if ($this->isEntityUsingFieldOverride($entity, $view_mode)) {
         if (!$entity->isNew() && isset($entity->original)) {
-          if (empty($this->getEntitySections($entity->original))) {
+          if (empty($this->getEntitySections($entity->original, $view_mode))) {
             // If there were no sections in the original entity then this is a
             // new override from a default and the blocks need to be duplicated.
             $duplicate_blocks = TRUE;
diff --git a/core/modules/layout_builder/src/LayoutEntityHelperTrait.php b/core/modules/layout_builder/src/LayoutEntityHelperTrait.php
index 9124027542..907b8018f3 100644
--- a/core/modules/layout_builder/src/LayoutEntityHelperTrait.php
+++ b/core/modules/layout_builder/src/LayoutEntityHelperTrait.php
@@ -4,8 +4,8 @@
 
 use Drupal\Component\Plugin\DerivativeInspectionInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\FieldableEntityInterface;
-use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
+use Drupal\Core\Plugin\Context\Context;
+use Drupal\Core\Plugin\Context\ContextDefinition;
 
 /**
  * Methods to help with entities using the layout builder.
@@ -19,12 +19,14 @@
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity to check.
+   * @param string $view_mode
+   *   The view mode.
    *
    * @return bool
    *   TRUE if the entity can have a layout otherwise FALSE.
    */
-  protected function isLayoutCompatibleEntity(EntityInterface $entity) {
-    return $entity instanceof LayoutEntityDisplayInterface || $this->isEntityUsingFieldOverride($entity);
+  protected function isLayoutCompatibleEntity(EntityInterface $entity, $view_mode) {
+    return (bool) $this->getSectionStorageFromEntity($entity, $view_mode);
   }
 
   /**
@@ -47,27 +49,42 @@ protected function getInlineBlockRevisionIdsInSections(array $sections) {
     return $revision_ids;
   }
 
+  /**
+   * Gets the section storage given an entity and view mode.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity.
+   * @param string $view_mode
+   *   The view mode.
+   *
+   * @return \Drupal\layout_builder\SectionStorageInterface|null
+   *   The section storage, if it exists.
+   */
+  private function getSectionStorageFromEntity(EntityInterface $entity, $view_mode) {
+    /** @var \Drupal\layout_builder\SectionStorageInterface $storage */
+    return \Drupal::service('plugin.manager.layout_builder.section_storage')
+      ->loadFromContext([
+        'view_mode' => new Context(ContextDefinition::create('string'), $view_mode),
+        // @todo Use EntityContext::fromEntity() after
+        //   https://www.drupal.org/project/drupal/issues/3008431 is fixed.
+        'entity' => new Context(ContextDefinition::create('entity'), $entity),
+      ]);
+  }
+
   /**
    * Gets the sections for an entity if any.
    *
-   * @todo Replace this method with calls to the SectionStorageManagerInterface
-   * method for getting sections from an entity in
-   * https://www.drupal.org/node/2986403.
-   *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity.
+   * @param string $view_mode
+   *   The view mode.
    *
-   * @return \Drupal\layout_builder\Section[]|null
+   * @return \Drupal\layout_builder\Section[]
    *   The entity layout sections if available.
    */
-  protected function getEntitySections(EntityInterface $entity) {
-    if ($entity instanceof LayoutEntityDisplayInterface) {
-      return $entity->getSections();
-    }
-    elseif ($this->isEntityUsingFieldOverride($entity)) {
-      return $entity->get('layout_builder__layout')->getSections();
-    }
-    return NULL;
+  protected function getEntitySections(EntityInterface $entity, $view_mode) {
+    $storage = $this->getSectionStorageFromEntity($entity, $view_mode);
+    return $storage ? $storage->getSections() : [];
   }
 
   /**
@@ -97,12 +114,15 @@ protected function getInlineBlockComponents(array $sections) {
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity.
+   * @param string $view_mode
+   *   The view mode.
    *
    * @return bool
    *   TRUE if the entity is using a field for a layout override.
    */
-  protected function isEntityUsingFieldOverride(EntityInterface $entity) {
-    return $entity instanceof FieldableEntityInterface && $entity->hasField('layout_builder__layout');
+  protected function isEntityUsingFieldOverride(EntityInterface $entity, $view_mode) {
+    $storage = $this->getSectionStorageFromEntity($entity, $view_mode);
+    return $storage && $storage->getPluginId() === 'overrides';
   }
 
 }
diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php
index d35041d03d..24c230055c 100644
--- a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php
+++ b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php
@@ -15,8 +15,6 @@
 use Drupal\field_ui\FieldUI;
 use Drupal\layout_builder\DefaultsSectionStorageInterface;
 use Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator;
-use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
-use Drupal\layout_builder\SectionListInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -25,6 +23,9 @@
  *
  * @SectionStorage(
  *   id = "defaults",
+ *   context = {
+ *     "entity" = @ContextDefinition("entity:entity_view_display"),
+ *   },
  * )
  *
  * @internal
@@ -90,12 +91,8 @@ public static function create(ContainerInterface $container, array $configuratio
   /**
    * {@inheritdoc}
    */
-  public function setSectionList(SectionListInterface $section_list) {
-    if (!$section_list instanceof LayoutEntityDisplayInterface) {
-      throw new \InvalidArgumentException('Defaults expect a display-based section list');
-    }
-
-    return parent::setSectionList($section_list);
+  protected function getSectionList() {
+    return $this->getContextValue('entity');
   }
 
   /**
@@ -237,34 +234,41 @@ protected function getEntityTypes() {
   /**
    * {@inheritdoc}
    */
-  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
-    if (is_string($value) && strpos($value, '.') !== FALSE) {
-      return $value;
+  public function getContextsFromRoute($value, $definition, $name, array $defaults) {
+    $contexts = [];
+
+    if ($entity = $this->extractEntityFromRoute($value, $defaults)) {
+      $contexts['entity'] = EntityContext::fromEntity($entity);
     }
+    return $contexts;
+  }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function extractEntityFromRoute($value, array $defaults) {
     // If a bundle is not provided but a value corresponding to the bundle key
     // is, use that for the bundle value.
     if (empty($defaults['bundle']) && isset($defaults['bundle_key']) && !empty($defaults[$defaults['bundle_key']])) {
       $defaults['bundle'] = $defaults[$defaults['bundle_key']];
     }
 
-    if (!empty($defaults['entity_type_id']) && !empty($defaults['bundle']) && !empty($defaults['view_mode_name'])) {
-      return $defaults['entity_type_id'] . '.' . $defaults['bundle'] . '.' . $defaults['view_mode_name'];
+    if (is_string($value) && strpos($value, '.') !== FALSE) {
+      list($entity_type_id, $bundle, $view_mode) = explode('.', $value, 3);
     }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSectionListFromId($id) {
-    if (strpos($id, '.') === FALSE) {
-      throw new \InvalidArgumentException(sprintf('The "%s" ID for the "%s" section storage type is invalid', $id, $this->getStorageType()));
+    elseif (!empty($defaults['entity_type_id']) && !empty($defaults['bundle']) && !empty($defaults['view_mode_name'])) {
+      $entity_type_id = $defaults['entity_type_id'];
+      $bundle = $defaults['bundle'];
+      $view_mode = $defaults['view_mode_name'];
+      $value = "$entity_type_id.$bundle.$view_mode";
+    }
+    else {
+      return NULL;
     }
 
     $storage = $this->entityTypeManager->getStorage('entity_view_display');
     // If the display does not exist, create a new one.
-    if (!$display = $storage->load($id)) {
-      list($entity_type_id, $bundle, $view_mode) = explode('.', $id, 3);
+    if (!$display = $storage->load($value)) {
       $display = $storage->create([
         'targetEntityType' => $entity_type_id,
         'bundle' => $bundle,
diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
index c623c5ede3..4eec93230b 100644
--- a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
+++ b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
@@ -7,14 +7,12 @@
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
-use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\Context\EntityContext;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
 use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
 use Drupal\layout_builder\OverridesSectionStorageInterface;
-use Drupal\layout_builder\SectionListInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -23,6 +21,10 @@
  *
  * @SectionStorage(
  *   id = "overrides",
+ *   context = {
+ *     "entity" = @ContextDefinition("entity"),
+ *     "view_mode" = @ContextDefinition("string", required = FALSE),
+ *   }
  * )
  *
  * @internal
@@ -79,12 +81,8 @@ public static function create(ContainerInterface $container, array $configuratio
   /**
    * {@inheritdoc}
    */
-  public function setSectionList(SectionListInterface $section_list) {
-    if (!$section_list instanceof FieldItemListInterface) {
-      throw new \InvalidArgumentException('Overrides expect a field-based section list');
-    }
-
-    return parent::setSectionList($section_list);
+  protected function getSectionList() {
+    return $this->getEntity()->get('layout_builder__layout');
   }
 
   /**
@@ -94,7 +92,7 @@ public function setSectionList(SectionListInterface $section_list) {
    *   The entity storing the overrides.
    */
   protected function getEntity() {
-    return $this->getSectionList()->getEntity();
+    return $this->getContextValue('entity');
   }
 
   /**
@@ -108,30 +106,34 @@ public function getStorageId() {
   /**
    * {@inheritdoc}
    */
-  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+  public function getContextsFromRoute($value, $definition, $name, array $defaults) {
+    $contexts = [];
+
+    if ($entity = $this->extractEntityFromRoute($value, $defaults)) {
+      $contexts['entity'] = EntityContext::fromEntity($entity);
+    }
+    return $contexts;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function extractEntityFromRoute($value, array $defaults) {
     if (strpos($value, '.') !== FALSE) {
-      return $value;
+      list($entity_type_id, $entity_id) = explode('.', $value, 2);
     }
-
-    if (isset($defaults['entity_type_id']) && !empty($defaults[$defaults['entity_type_id']])) {
+    elseif (isset($defaults['entity_type_id']) && !empty($defaults[$defaults['entity_type_id']])) {
       $entity_type_id = $defaults['entity_type_id'];
       $entity_id = $defaults[$entity_type_id];
-      return $entity_type_id . '.' . $entity_id;
     }
-  }
+    else {
+      return NULL;
+    }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getSectionListFromId($id) {
-    if (strpos($id, '.') !== FALSE) {
-      list($entity_type_id, $entity_id) = explode('.', $id, 2);
-      $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($entity_id);
-      if ($entity instanceof FieldableEntityInterface && $entity->hasField('layout_builder__layout')) {
-        return $entity->get('layout_builder__layout');
-      }
+    $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($entity_id);
+    if ($entity instanceof FieldableEntityInterface && $entity->hasField('layout_builder__layout')) {
+      return $entity;
     }
-    throw new \InvalidArgumentException(sprintf('The "%s" ID for the "%s" section storage type is invalid', $id, $this->getStorageType()));
   }
 
   /**
diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php b/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
index c419060c45..8e8178355b 100644
--- a/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
+++ b/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
@@ -2,10 +2,9 @@
 
 namespace Drupal\layout_builder\Plugin\SectionStorage;
 
-use Drupal\Core\Plugin\PluginBase;
+use Drupal\Core\Plugin\ContextAwarePluginBase;
 use Drupal\layout_builder\Routing\LayoutBuilderRoutesTrait;
 use Drupal\layout_builder\Section;
-use Drupal\layout_builder\SectionListInterface;
 use Drupal\layout_builder\SectionStorageInterface;
 
 /**
@@ -16,40 +15,17 @@
  *   experimental modules and development releases of contributed modules.
  *   See https://www.drupal.org/core/experimental for more information.
  */
-abstract class SectionStorageBase extends PluginBase implements SectionStorageInterface {
+abstract class SectionStorageBase extends ContextAwarePluginBase implements SectionStorageInterface {
 
   use LayoutBuilderRoutesTrait;
 
-  /**
-   * The section storage instance.
-   *
-   * @var \Drupal\layout_builder\SectionListInterface|null
-   */
-  protected $sectionList;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSectionList(SectionListInterface $section_list) {
-    $this->sectionList = $section_list;
-    return $this;
-  }
-
   /**
    * Gets the section list.
    *
    * @return \Drupal\layout_builder\SectionListInterface
    *   The section list.
-   *
-   * @throws \RuntimeException
-   *   Thrown if ::setSectionList() is not called first.
    */
-  protected function getSectionList() {
-    if (!$this->sectionList) {
-      throw new \RuntimeException(sprintf('%s::setSectionList() must be called first', static::class));
-    }
-    return $this->sectionList;
-  }
+  abstract protected function getSectionList();
 
   /**
    * {@inheritdoc}
@@ -103,4 +79,22 @@ public function removeSection($delta) {
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   *
+   * @todo Remove after https://www.drupal.org/project/drupal/issues/2982626.
+   */
+  public function getContextDefinition($name) {
+    return $this->getPluginDefinition()->getContextDefinition($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @todo Remove after https://www.drupal.org/project/drupal/issues/2982626.
+   */
+  public function getContextDefinitions() {
+    return $this->getPluginDefinition()->getContextDefinitions();
+  }
+
 }
diff --git a/core/modules/layout_builder/src/SectionStorage/SectionStorageDefinition.php b/core/modules/layout_builder/src/SectionStorage/SectionStorageDefinition.php
index 61b975a471..4c3bac2c49 100644
--- a/core/modules/layout_builder/src/SectionStorage/SectionStorageDefinition.php
+++ b/core/modules/layout_builder/src/SectionStorage/SectionStorageDefinition.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\layout_builder\SectionStorage;
 
+use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionTrait;
 use Drupal\Component\Plugin\Definition\PluginDefinition;
 
 /**
@@ -12,7 +14,9 @@
  *   experimental modules and development releases of contributed modules.
  *   See https://www.drupal.org/core/experimental for more information.
  */
-class SectionStorageDefinition extends PluginDefinition {
+class SectionStorageDefinition extends PluginDefinition implements ContextAwarePluginDefinitionInterface {
+
+  use ContextAwarePluginDefinitionTrait;
 
   /**
    * Any additional properties and values.
@@ -28,6 +32,16 @@ class SectionStorageDefinition extends PluginDefinition {
    *   An array of values from the annotation.
    */
   public function __construct(array $definition = []) {
+    // If there are context definitions in the plugin definition, they should
+    // be added to this object using ::addContextDefinition() so that they can
+    // be manipulated using other ContextAwarePluginDefinitionInterface methods.
+    if (isset($definition['context'])) {
+      foreach ($definition['context'] as $name => $context_definition) {
+        $this->addContextDefinition($name, $context_definition);
+      }
+      unset($definition['context']);
+    }
+
     foreach ($definition as $property => $value) {
       $this->set($property, $value);
     }
diff --git a/core/modules/layout_builder/src/SectionStorage/SectionStorageManager.php b/core/modules/layout_builder/src/SectionStorage/SectionStorageManager.php
index 18147cd1d8..933ebd29b6 100644
--- a/core/modules/layout_builder/src/SectionStorage/SectionStorageManager.php
+++ b/core/modules/layout_builder/src/SectionStorage/SectionStorageManager.php
@@ -2,8 +2,10 @@
 
 namespace Drupal\layout_builder\SectionStorage;
 
+use Drupal\Component\Utility\SortArray;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\Context\ContextAwarePluginManagerTrait;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Drupal\layout_builder\Annotation\SectionStorage;
 use Drupal\layout_builder\SectionStorageInterface;
@@ -18,6 +20,8 @@
  */
 class SectionStorageManager extends DefaultPluginManager implements SectionStorageManagerInterface {
 
+  use ContextAwarePluginManagerTrait;
+
   /**
    * Constructs a new SectionStorageManager object.
    *
@@ -36,6 +40,25 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
     $this->setCacheBackend($cache_backend, 'layout_builder_section_storage_plugins');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function findDefinitions() {
+    $definitions = parent::findDefinitions();
+
+    // Sort the definitions before they are cached.
+    uasort($definitions, function (SectionStorageDefinition $a, SectionStorageDefinition $b) {
+      $a = [
+        'weight' => $a->get('weight'),
+      ];
+      $b = [
+        'weight' => $b->get('weight'),
+      ];
+      return SortArray::sortByWeightElement($a, $b);
+    });
+    return $definitions;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -46,10 +69,23 @@ public function loadEmpty($id) {
   /**
    * {@inheritdoc}
    */
-  public function loadFromStorageId($type, $id) {
-    /** @var \Drupal\layout_builder\SectionStorageInterface $plugin */
-    $plugin = $this->createInstance($type);
-    return $plugin->setSectionList($plugin->getSectionListFromId($id));
+  public function loadFromContext(array $contexts) {
+    $storage_types = array_keys($this->getDefinitionsForContexts($contexts));
+
+    foreach ($storage_types as $type) {
+      /** @var \Drupal\layout_builder\SectionStorageInterface $plugin */
+      $plugin = $this->createInstance($type);
+
+      foreach ($contexts as $name => $context) {
+        $plugin->setContext($name, $context);
+      }
+      // Now that all contexts are set, the storage has the final say on whether
+      // it should be used or not.
+      if ($plugin->access('load')) {
+        return $plugin;
+      }
+    }
+    return NULL;
   }
 
   /**
@@ -58,14 +94,18 @@ public function loadFromStorageId($type, $id) {
   public function loadFromRoute($type, $value, $definition, $name, array $defaults) {
     /** @var \Drupal\layout_builder\SectionStorageInterface $plugin */
     $plugin = $this->createInstance($type);
-    if ($id = $plugin->extractIdFromRoute($value, $definition, $name, $defaults)) {
-      try {
-        return $plugin->setSectionList($plugin->getSectionListFromId($id));
-      }
-      catch (\InvalidArgumentException $e) {
-        // Intentionally empty.
-      }
+
+    try {
+      $contexts = $plugin->getContextsFromRoute($value, $definition, $name, $defaults);
     }
+    catch (\InvalidArgumentException $e) {
+      $contexts = [];
+    }
+
+    foreach ($contexts as $name => $context) {
+      $plugin->setContext($name, $context);
+    }
+    return $contexts ? $plugin : NULL;
   }
 
 }
diff --git a/core/modules/layout_builder/src/SectionStorage/SectionStorageManagerInterface.php b/core/modules/layout_builder/src/SectionStorage/SectionStorageManagerInterface.php
index 3b269fcbba..b7627e9a4a 100644
--- a/core/modules/layout_builder/src/SectionStorage/SectionStorageManagerInterface.php
+++ b/core/modules/layout_builder/src/SectionStorage/SectionStorageManagerInterface.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\layout_builder\SectionStorage;
 
-use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Core\Plugin\Context\ContextAwarePluginManagerInterface;
 
 /**
  * Provides the interface for a plugin manager of section storage types.
@@ -12,7 +12,7 @@
  *   experimental modules and development releases of contributed modules.
  *   See https://www.drupal.org/core/experimental for more information.
  */
-interface SectionStorageManagerInterface extends DiscoveryInterface {
+interface SectionStorageManagerInterface extends ContextAwarePluginManagerInterface {
 
   /**
    * Loads a section storage with no associated section list.
@@ -26,20 +26,15 @@
   public function loadEmpty($id);
 
   /**
-   * Loads a section storage populated with an existing section list.
+   * Loads a section storage populated with a section list derived from context.
    *
-   * @param string $type
-   *   The section storage type.
-   * @param string $id
-   *   The section list ID.
+   * @param \Drupal\Component\Plugin\Context\ContextInterface[] $contexts
+   *   The contexts which should be used to determine which storage to load.
    *
-   * @return \Drupal\layout_builder\SectionStorageInterface
-   *   The section storage.
-   *
-   * @throws \InvalidArgumentException
-   *   Thrown if the ID is invalid.
+   * @return \Drupal\layout_builder\SectionStorageInterface|null
+   *   The section storage if one matched all contexts, or NULL otherwise.
    */
-  public function loadFromStorageId($type, $id);
+  public function loadFromContext(array $contexts);
 
   /**
    * Loads a section storage populated with a section list derived from a route.
diff --git a/core/modules/layout_builder/src/SectionStorageInterface.php b/core/modules/layout_builder/src/SectionStorageInterface.php
index 90ce9072fd..a77c838620 100644
--- a/core/modules/layout_builder/src/SectionStorageInterface.php
+++ b/core/modules/layout_builder/src/SectionStorageInterface.php
@@ -2,8 +2,8 @@
 
 namespace Drupal\layout_builder;
 
-use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Access\AccessibleInterface;
+use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
@@ -14,7 +14,7 @@
  *   experimental modules and development releases of contributed modules.
  *   See https://www.drupal.org/core/experimental for more information.
  */
-interface SectionStorageInterface extends SectionListInterface, PluginInspectionInterface, AccessibleInterface {
+interface SectionStorageInterface extends SectionListInterface, ContextAwarePluginInterface, AccessibleInterface {
 
   /**
    * Returns an identifier for this storage.
@@ -34,36 +34,6 @@ public function getStorageId();
    */
   public function getStorageType();
 
-  /**
-   * Sets the section list on the storage.
-   *
-   * @param \Drupal\layout_builder\SectionListInterface $section_list
-   *   The section list.
-   *
-   * @return $this
-   *
-   * @internal
-   *   This should only be called during section storage instantiation.
-   */
-  public function setSectionList(SectionListInterface $section_list);
-
-  /**
-   * Derives the section list from the storage ID.
-   *
-   * @param string $id
-   *   The storage ID, see ::getStorageId().
-   *
-   * @return \Drupal\layout_builder\SectionListInterface
-   *   The section list.
-   *
-   * @throws \InvalidArgumentException
-   *   Thrown if the ID is invalid.
-   *
-   * @internal
-   *   This should only be called during section storage instantiation.
-   */
-  public function getSectionListFromId($id);
-
   /**
    * Provides the routes needed for Layout Builder UI.
    *
@@ -99,7 +69,7 @@ public function getRedirectUrl();
   public function getLayoutBuilderUrl($rel = 'view');
 
   /**
-   * Configures the plugin based on route values.
+   * Derives the required plugin contexts from route values.
    *
    * @param mixed $value
    *   The raw value.
@@ -110,21 +80,10 @@ public function getLayoutBuilderUrl($rel = 'view');
    * @param array $defaults
    *   The route defaults array.
    *
-   * @return string|null
-   *   The section storage ID if it could be extracted, NULL otherwise.
-   *
-   * @internal
-   *   This should only be called during section storage instantiation.
+   * @return \Drupal\Component\Plugin\Context\ContextInterface[]
+   *   The required plugin contexts.
    */
-  public function extractIdFromRoute($value, $definition, $name, array $defaults);
-
-  /**
-   * Provides any available contexts for the object using the sections.
-   *
-   * @return \Drupal\Core\Plugin\Context\ContextInterface[]
-   *   The array of context objects.
-   */
-  public function getContexts();
+  public function getContextsFromRoute($value, $definition, $name, array $defaults);
 
   /**
    * Gets the label for the object using the sections.
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
index e7d310a6cb..8e9991f8cd 100644
--- a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\layout_builder_test\Plugin\SectionStorage\TestOverridesSectionStorage;
 
 /**
  * Implements hook_plugin_filter_TYPE__CONSUMER_alter().
@@ -58,3 +59,15 @@ function layout_builder_test_node_view(array &$build, EntityInterface $entity, E
     ];
   }
 }
+
+/**
+ * Implements hook_layout_builder_section_storage_alter().
+ */
+function layout_builder_test_layout_builder_section_storage_alter(array &$storages) {
+  /** @var \Drupal\layout_builder\SectionStorage\SectionStorageDefinition[] $storages */
+  $storages['overrides']->setClass(TestOverridesSectionStorage::class);
+  $storages['overrides']->set('weight', -10);
+
+  $storages['overrides_heavy'] = clone $storages['overrides'];
+  $storages['overrides_heavy']->set('weight', -8);
+}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/TestOverridesSectionStorage.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/TestOverridesSectionStorage.php
new file mode 100644
index 0000000000..d4fd459343
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/TestOverridesSectionStorage.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\layout_builder_test\Plugin\SectionStorage;
+
+use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
+
+/**
+ * Provides a test override of section storage.
+ */
+class TestOverridesSectionStorage extends OverridesSectionStorage {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getSectionList() {
+    \Drupal::state()->set('layout_builder_test_storage', [
+      $this->getPluginDefinition()->get('weight'),
+      $this->getContextValue('view_mode'),
+    ]);
+    return parent::getSectionList();
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index 1e4f240869..3c2301f62b 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -526,4 +526,31 @@ public function testBlockPlaceholder() {
     $assert_session->pageTextContains($block_content);
   }
 
+  /**
+   * Tests that section loading is delegated to plugins during rendering.
+   */
+  public function testRenderByContextualPluginDelegate() {
+    $state_key = 'layout_builder_test_storage';
+    /** @var \Drupal\Core\State\StateInterface $state */
+    $state = $this->container->get('state');
+
+    $this->drupalGet('node/1');
+    $this->assertEmpty($state->get($state_key));
+
+    entity_get_display('node', 'bundle_with_section_field', 'full')
+      ->enableLayoutBuilder()
+      ->setOverridable()
+      ->save();
+
+    $this->getSession()->reload();
+    $state->resetCache();
+    // During layout rendering, the storage plugin used for testing will set the
+    // state key to an array containing the plugin weight and view mode, which
+    // proves that the plugin matched the appropriate contexts and was actually
+    // used to render the layout.
+    list ($weight, $view_mode) = $state->get($state_key);
+    $this->assertSame(-10, $weight);
+    $this->assertSame('full', $view_mode);
+  }
+
 }
diff --git a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php
index d30917a446..726d62dcab 100644
--- a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Plugin\Context\ContextInterface;
 use Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator;
 use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
 use Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage;
@@ -61,8 +62,12 @@ protected function setUp() {
   public function testThirdPartySettings() {
     // Set an initial value on the section list.
     $section_list = $this->prophesize(LayoutEntityDisplayInterface::class);
+
+    $context = $this->prophesize(ContextInterface::class);
+    $context->getContextValue()->willReturn($section_list->reveal());
+    $this->plugin->setContext('entity', $context->reveal());
+
     $section_list->getThirdPartySetting('the_module', 'the_key', NULL)->willReturn('value 1');
-    $this->plugin->setSectionList($section_list->reveal());
 
     // The plugin returns the initial value.
     $this->assertSame('value 1', $this->plugin->getThirdPartySetting('the_module', 'the_key'));
@@ -79,58 +84,11 @@ public function testThirdPartySettings() {
   }
 
   /**
-   * @covers ::extractIdFromRoute
+   * @covers ::extractEntityFromRoute
    *
-   * @dataProvider providerTestExtractIdFromRoute
+   * @dataProvider providerTestExtractEntityFromRoute
    */
-  public function testExtractIdFromRoute($expected, $value, array $defaults) {
-    $result = $this->plugin->extractIdFromRoute($value, [], 'the_parameter_name', $defaults);
-    $this->assertSame($expected, $result);
-  }
-
-  /**
-   * Provides data for ::testExtractIdFromRoute().
-   */
-  public function providerTestExtractIdFromRoute() {
-    $data = [];
-    $data['with value'] = [
-      'foo.bar.baz',
-      'foo.bar.baz',
-      [],
-    ];
-    $data['empty value, without bundle'] = [
-      'my_entity_type.bundle_name.default',
-      '',
-      [
-        'entity_type_id' => 'my_entity_type',
-        'view_mode_name' => 'default',
-        'bundle_key' => 'my_bundle',
-        'my_bundle' => 'bundle_name',
-      ],
-    ];
-    $data['empty value, with bundle'] = [
-      'my_entity_type.bundle_name.default',
-      '',
-      [
-        'entity_type_id' => 'my_entity_type',
-        'view_mode_name' => 'default',
-        'bundle' => 'bundle_name',
-      ],
-    ];
-    $data['without value, empty defaults'] = [
-      NULL,
-      '',
-      [],
-    ];
-    return $data;
-  }
-
-  /**
-   * @covers ::getSectionListFromId
-   *
-   * @dataProvider providerTestGetSectionListFromId
-   */
-  public function testGetSectionListFromId($success, $expected_entity_id, $value) {
+  public function testExtractEntityFromRoute($success, $expected_entity_id, $value, array $defaults = []) {
     if ($expected_entity_id) {
       $entity_storage = $this->prophesize(EntityStorageInterface::class);
       $entity_storage->load($expected_entity_id)->willReturn('the_return_value');
@@ -143,26 +101,48 @@ public function testGetSectionListFromId($success, $expected_entity_id, $value)
       $this->entityTypeManager->getStorage('entity_view_display')->shouldNotBeCalled();
     }
 
-    if (!$success) {
-      $this->setExpectedException(\InvalidArgumentException::class);
-    }
-
-    $result = $this->plugin->getSectionListFromId($value);
+    $method = new \ReflectionMethod($this->plugin, 'extractEntityFromRoute');
+    $method->setAccessible(TRUE);
+    $result = $method->invoke($this->plugin, $value, $defaults);
     if ($success) {
       $this->assertEquals('the_return_value', $result);
     }
+    else {
+      $this->assertNull($result);
+    }
   }
 
   /**
-   * Provides data for ::testGetSectionListFromId().
+   * Provides data for ::testExtractEntityFromRoute().
    */
-  public function providerTestGetSectionListFromId() {
+  public function providerTestExtractEntityFromRoute() {
     $data = [];
     $data['with value'] = [
       TRUE,
       'foo.bar.baz',
       'foo.bar.baz',
     ];
+    $data['empty value, without bundle'] = [
+      TRUE,
+      'my_entity_type.bundle_name.default',
+      '',
+      [
+        'entity_type_id' => 'my_entity_type',
+        'view_mode_name' => 'default',
+        'bundle_key' => 'my_bundle',
+        'my_bundle' => 'bundle_name',
+      ],
+    ];
+    $data['empty value, with bundle'] = [
+      TRUE,
+      'my_entity_type.bundle_name.default',
+      '',
+      [
+        'entity_type_id' => 'my_entity_type',
+        'view_mode_name' => 'default',
+        'bundle' => 'bundle_name',
+      ],
+    ];
     $data['without value, empty defaults'] = [
       FALSE,
       NULL,
@@ -172,9 +152,9 @@ public function providerTestGetSectionListFromId() {
   }
 
   /**
-   * @covers ::getSectionListFromId
+   * @covers ::extractEntityFromRoute
    */
-  public function testGetSectionListFromIdCreate() {
+  public function testExtractEntityFromRouteCreate() {
     $expected = 'the_return_value';
     $value = 'foo.bar.baz';
     $expected_create_values = [
@@ -190,7 +170,9 @@ public function testGetSectionListFromIdCreate() {
     $this->entityTypeManager->getDefinition('entity_view_display')->willReturn(new EntityType(['id' => 'entity_view_display']));
     $this->entityTypeManager->getStorage('entity_view_display')->willReturn($entity_storage->reveal());
 
-    $result = $this->plugin->getSectionListFromId($value);
+    $method = new \ReflectionMethod($this->plugin, 'extractEntityFromRoute');
+    $method->setAccessible(TRUE);
+    $result = $method->invoke($this->plugin, $value, []);
     $this->assertSame($expected, $result);
   }
 
diff --git a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
index 110ec2021e..d3574be6dd 100644
--- a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
@@ -60,87 +60,42 @@ protected function setUp() {
   }
 
   /**
-   * @covers ::extractIdFromRoute
+   * @covers ::extractEntityFromRoute
    *
-   * @dataProvider providerTestExtractIdFromRoute
+   * @dataProvider providerTestExtractEntityFromRoute
    */
-  public function testExtractIdFromRoute($expected, $value, array $defaults) {
-    $result = $this->plugin->extractIdFromRoute($value, [], 'the_parameter_name', $defaults);
-    $this->assertSame($expected, $result);
-  }
-
-  /**
-   * Provides data for ::testExtractIdFromRoute().
-   */
-  public function providerTestExtractIdFromRoute() {
-    $data = [];
-    $data['with value, with layout'] = [
-      'my_entity_type.entity_with_layout',
-      'my_entity_type.entity_with_layout',
-      [],
-    ];
-    $data['with value, without layout'] = [
-      NULL,
-      'my_entity_type',
-      [],
-    ];
-    $data['empty value, populated defaults'] = [
-      'my_entity_type.entity_with_layout',
-      '',
-      [
-        'entity_type_id' => 'my_entity_type',
-        'my_entity_type' => 'entity_with_layout',
-      ],
-    ];
-    $data['empty value, empty defaults'] = [
-      NULL,
-      '',
-      [],
-    ];
-    return $data;
-  }
-
-  /**
-   * @covers ::getSectionListFromId
-   *
-   * @dataProvider providerTestGetSectionListFromId
-   */
-  public function testGetSectionListFromId($success, $expected_entity_type_id, $id) {
-    $defaults['the_parameter_name'] = $id;
-
+  public function testExtractEntityFromRoute($success, $expected_entity_type_id, $value, array $defaults = []) {
     if ($expected_entity_type_id) {
       $entity_storage = $this->prophesize(EntityStorageInterface::class);
 
       $entity_without_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_without_layout->hasField('layout_builder__layout')->willReturn(FALSE);
-      $entity_without_layout->get('layout_builder__layout')->shouldNotBeCalled();
       $entity_storage->load('entity_without_layout')->willReturn($entity_without_layout->reveal());
 
       $entity_with_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_with_layout->hasField('layout_builder__layout')->willReturn(TRUE);
-      $entity_with_layout->get('layout_builder__layout')->willReturn('the_return_value');
       $entity_storage->load('entity_with_layout')->willReturn($entity_with_layout->reveal());
-
       $this->entityTypeManager->getStorage($expected_entity_type_id)->willReturn($entity_storage->reveal());
     }
     else {
       $this->entityTypeManager->getStorage(Argument::any())->shouldNotBeCalled();
     }
 
-    if (!$success) {
-      $this->setExpectedException(\InvalidArgumentException::class);
-    }
-
-    $result = $this->plugin->getSectionListFromId($id);
+    $method = new \ReflectionMethod($this->plugin, 'extractEntityFromRoute');
+    $method->setAccessible(TRUE);
+    $result = $method->invoke($this->plugin, $value, $defaults);
     if ($success) {
-      $this->assertEquals('the_return_value', $result);
+      $this->assertInstanceOf(FieldableEntityInterface::class, $result);
+    }
+    else {
+      $this->assertNull($result);
     }
   }
 
   /**
-   * Provides data for ::testGetSectionListFromId().
+   * Provides data for ::testExtractEntityFromRoute().
    */
-  public function providerTestGetSectionListFromId() {
+  public function providerTestExtractEntityFromRoute() {
     $data = [];
     $data['with value, with layout'] = [
       TRUE,
@@ -152,6 +107,15 @@ public function providerTestGetSectionListFromId() {
       'my_entity_type',
       'my_entity_type.entity_without_layout',
     ];
+    $data['empty value, populated defaults'] = [
+      TRUE,
+      'my_entity_type',
+      '',
+      [
+        'entity_type_id' => 'my_entity_type',
+        'my_entity_type' => 'entity_with_layout',
+      ],
+    ];
     $data['empty value, empty defaults'] = [
       FALSE,
       NULL,
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
index 392cd8939e..10f41e937c 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
@@ -2,10 +2,10 @@
 
 namespace Drupal\Tests\layout_builder\Unit;
 
+use Drupal\Component\Plugin\Context\ContextInterface;
 use Drupal\Component\Plugin\Factory\FactoryInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\layout_builder\SectionListInterface;
 use Drupal\layout_builder\SectionStorage\SectionStorageManager;
 use Drupal\layout_builder\SectionStorageInterface;
 use Drupal\Tests\UnitTestCase;
@@ -58,30 +58,15 @@ public function testLoadEmpty() {
     $this->assertInstanceOf(SectionStorageInterface::class, $result);
   }
 
-  /**
-   * @covers ::loadFromStorageId
-   */
-  public function testLoadFromStorageId() {
-    $section_list = $this->prophesize(SectionListInterface::class);
-    $this->plugin->setSectionList($section_list->reveal())->will(function () {
-      return $this;
-    });
-    $this->plugin->getSectionListFromId('the_storage_id')->willReturn($section_list->reveal());
-
-    $result = $this->manager->loadFromStorageId('the_plugin_id', 'the_storage_id');
-    $this->assertInstanceOf(SectionStorageInterface::class, $result);
-  }
-
   /**
    * @covers ::loadFromRoute
    */
   public function testLoadFromRoute() {
-    $section_list = $this->prophesize(SectionListInterface::class);
-    $this->plugin->extractIdFromRoute('the_value', [], 'the_parameter_name', [])->willReturn('the_storage_id');
-    $this->plugin->getSectionListFromId('the_storage_id')->willReturn($section_list->reveal());
-    $this->plugin->setSectionList($section_list->reveal())->will(function () {
-      return $this;
-    });
+    $contexts = [
+      'the_context' => $this->prophesize(ContextInterface::class)->reveal(),
+    ];
+    $this->plugin->getContextsFromRoute('the_value', [], 'the_parameter_name', [])->willReturn($contexts);
+    $this->plugin->setContext('the_context', $contexts['the_context'])->shouldBeCalled();
 
     $result = $this->manager->loadFromRoute('the_plugin_id', 'the_value', [], 'the_parameter_name', []);
     $this->assertInstanceOf(SectionStorageInterface::class, $result);
@@ -91,7 +76,7 @@ public function testLoadFromRoute() {
    * @covers ::loadFromRoute
    */
   public function testLoadFromRouteNull() {
-    $this->plugin->extractIdFromRoute('the_value', [], 'the_parameter_name', ['_route' => 'the_route_name'])->willReturn(NULL);
+    $this->plugin->getContextsFromRoute('the_value', [], 'the_parameter_name', ['_route' => 'the_route_name'])->willReturn([]);
 
     $result = $this->manager->loadFromRoute('the_plugin_id', 'the_value', [], 'the_parameter_name', ['_route' => 'the_route_name']);
     $this->assertNull($result);
