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..7e0cbc1791 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.
+   *
+   * 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.
+   *
+   * 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.
+   *
+   * @see \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::getRuntimeSections()
+   *
+   * @var array
+   */
+  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..781cbad31d 100644
--- a/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php
+++ b/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php
@@ -5,6 +5,8 @@
 use Drupal\Core\Entity\Entity\EntityViewDisplay as BaseEntityViewDisplay;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Plugin\Context\Context;
+use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Context\EntityContext;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\field\Entity\FieldConfig;
@@ -264,11 +266,24 @@ 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;
+
+    if ($this->isOverridable()) {
+      /** @var \Drupal\layout_builder\SectionStorageInterface $storage */
+      $storage = \Drupal::service('plugin.manager.layout_builder.section_storage')
+        ->loadFromContext([
+          'entity' => new Context(ContextDefinition::create('entity'), $entity),
+          'view_mode' => new Context(ContextDefinition::create('string'), $this->getMode()),
+        ]);
 
-    return $this->getSections();
+      if ($storage) {
+        $sections = $storage->getSections();
+      }
+    }
+    // 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/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php
index d35041d03d..854096bf03 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,43 +91,29 @@ 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);
-  }
-
-  /**
-   * Gets the entity storing the overrides.
-   *
-   * @return \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface
-   *   The entity storing the defaults.
-   */
-  protected function getDisplay() {
-    return $this->getSectionList();
+  protected function getSectionList() {
+    return $this->getContextValue('entity');
   }
 
   /**
    * {@inheritdoc}
    */
   public function getStorageId() {
-    return $this->getDisplay()->id();
+    return $this->getSectionList()->id();
   }
 
   /**
    * {@inheritdoc}
    */
   public function getRedirectUrl() {
-    return Url::fromRoute("entity.entity_view_display.{$this->getDisplay()->getTargetEntityTypeId()}.view_mode", $this->getRouteParameters());
+    return Url::fromRoute("entity.entity_view_display.{$this->getSectionList()->getTargetEntityTypeId()}.view_mode", $this->getRouteParameters());
   }
 
   /**
    * {@inheritdoc}
    */
   public function getLayoutBuilderUrl($rel = 'view') {
-    return Url::fromRoute("layout_builder.{$this->getStorageType()}.{$this->getDisplay()->getTargetEntityTypeId()}.$rel", $this->getRouteParameters());
+    return Url::fromRoute("layout_builder.{$this->getStorageType()}.{$this->getSectionList()->getTargetEntityTypeId()}.$rel", $this->getRouteParameters());
   }
 
   /**
@@ -136,7 +123,7 @@ public function getLayoutBuilderUrl($rel = 'view') {
    *   An associative array of parameter names and values.
    */
   protected function getRouteParameters() {
-    $display = $this->getDisplay();
+    $display = $this->getSectionList();
     $entity_type = $this->entityTypeManager->getDefinition($display->getTargetEntityTypeId());
     $route_parameters = FieldUI::getRouteBundleParameter($entity_type, $display->getTargetBundle());
     $route_parameters['view_mode_name'] = $display->getMode();
@@ -237,7 +224,21 @@ protected function getEntityTypes() {
   /**
    * {@inheritdoc}
    */
-  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+  public function getContextsFromRoute($value, $definition, $name, array $defaults) {
+    $contexts = [];
+
+    $id = $this->extractIdFromRoute($value, $definition, $name, $defaults);
+    if ($id) {
+      $section_list = $this->getSectionListFromId($id);
+      $contexts['entity'] = EntityContext::fromEntity($section_list);
+    }
+    return $contexts;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function extractIdFromRoute($value, $definition, $name, array $defaults) {
     if (is_string($value) && strpos($value, '.') !== FALSE) {
       return $value;
     }
@@ -256,7 +257,7 @@ public function extractIdFromRoute($value, $definition, $name, array $defaults)
   /**
    * {@inheritdoc}
    */
-  public function getSectionListFromId($id) {
+  protected 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()));
     }
@@ -279,7 +280,7 @@ public function getSectionListFromId($id) {
    * {@inheritdoc}
    */
   public function getContexts() {
-    $display = $this->getDisplay();
+    $display = $this->getSectionList();
     $entity = $this->sampleEntityGenerator->get($display->getTargetEntityTypeId(), $display->getTargetBundle());
 
     $contexts = [];
@@ -291,28 +292,28 @@ public function getContexts() {
    * {@inheritdoc}
    */
   public function label() {
-    return $this->getDisplay()->label();
+    return $this->getSectionList()->label();
   }
 
   /**
    * {@inheritdoc}
    */
   public function save() {
-    return $this->getDisplay()->save();
+    return $this->getSectionList()->save();
   }
 
   /**
    * {@inheritdoc}
    */
   public function isOverridable() {
-    return $this->getDisplay()->isOverridable();
+    return $this->getSectionList()->isOverridable();
   }
 
   /**
    * {@inheritdoc}
    */
   public function setOverridable($overridable = TRUE) {
-    $this->getDisplay()->setOverridable($overridable);
+    $this->getSectionList()->setOverridable($overridable);
     return $this;
   }
 
@@ -320,7 +321,7 @@ public function setOverridable($overridable = TRUE) {
    * {@inheritdoc}
    */
   public function setThirdPartySetting($module, $key, $value) {
-    $this->getDisplay()->setThirdPartySetting($module, $key, $value);
+    $this->getSectionList()->setThirdPartySetting($module, $key, $value);
     return $this;
   }
 
@@ -328,14 +329,14 @@ public function setThirdPartySetting($module, $key, $value) {
    * {@inheritdoc}
    */
   public function isLayoutBuilderEnabled() {
-    return $this->getDisplay()->isLayoutBuilderEnabled();
+    return $this->getSectionList()->isLayoutBuilderEnabled();
   }
 
   /**
    * {@inheritdoc}
    */
   public function enableLayoutBuilder() {
-    $this->getDisplay()->enableLayoutBuilder();
+    $this->getSectionList()->enableLayoutBuilder();
     return $this;
   }
 
@@ -343,7 +344,7 @@ public function enableLayoutBuilder() {
    * {@inheritdoc}
    */
   public function disableLayoutBuilder() {
-    $this->getDisplay()->disableLayoutBuilder();
+    $this->getSectionList()->disableLayoutBuilder();
     return $this;
   }
 
@@ -351,21 +352,21 @@ public function disableLayoutBuilder() {
    * {@inheritdoc}
    */
   public function getThirdPartySetting($module, $key, $default = NULL) {
-    return $this->getDisplay()->getThirdPartySetting($module, $key, $default);
+    return $this->getSectionList()->getThirdPartySetting($module, $key, $default);
   }
 
   /**
    * {@inheritdoc}
    */
   public function getThirdPartySettings($module) {
-    return $this->getDisplay()->getThirdPartySettings($module);
+    return $this->getSectionList()->getThirdPartySettings($module);
   }
 
   /**
    * {@inheritdoc}
    */
   public function unsetThirdPartySetting($module, $key) {
-    $this->getDisplay()->unsetThirdPartySetting($module, $key);
+    $this->getSectionList()->unsetThirdPartySetting($module, $key);
     return $this;
   }
 
@@ -373,7 +374,7 @@ public function unsetThirdPartySetting($module, $key) {
    * {@inheritdoc}
    */
   public function getThirdPartyProviders() {
-    return $this->getDisplay()->getThirdPartyProviders();
+    return $this->getSectionList()->getThirdPartyProviders();
   }
 
   /**
diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
index c623c5ede3..cab3e1756f 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,9 @@
  *
  * @SectionStorage(
  *   id = "overrides",
+ *   context = {
+ *     "entity" = @ContextDefinition("entity"),
+ *   }
  * )
  *
  * @internal
@@ -79,12 +80,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 +91,7 @@ public function setSectionList(SectionListInterface $section_list) {
    *   The entity storing the overrides.
    */
   protected function getEntity() {
-    return $this->getSectionList()->getEntity();
+    return $this->getContextValue('entity');
   }
 
   /**
@@ -108,7 +105,22 @@ public function getStorageId() {
   /**
    * {@inheritdoc}
    */
-  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+  public function getContextsFromRoute($value, $definition, $name, array $defaults) {
+    $contexts = [];
+
+    $id = $this->extractIdFromRoute($value, $definition, $name, $defaults);
+    if ($id) {
+      $entity = $this->getSectionListFromId($id)->getEntity();
+      $contexts['entity'] = EntityContext::fromEntity($entity);
+    }
+    return $contexts;
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function extractIdFromRoute($value, $definition, $name, array $defaults) {
     if (strpos($value, '.') !== FALSE) {
       return $value;
     }
@@ -123,7 +135,7 @@ public function extractIdFromRoute($value, $definition, $name, array $defaults)
   /**
    * {@inheritdoc}
    */
-  public function getSectionListFromId($id) {
+  protected 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);
diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php b/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
index c419060c45..58a9470252 100644
--- a/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
+++ b/core/modules/layout_builder/src/Plugin/SectionStorage/SectionStorageBase.php
@@ -2,7 +2,7 @@
 
 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;
@@ -16,40 +16,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 +80,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..2dd54cbd7c 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,24 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
     $this->setCacheBackend($cache_backend, 'layout_builder_section_storage_plugins');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function findDefinitions() {
+    $definitions = parent::findDefinitions();
+
+    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 +68,21 @@ 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);
+      }
+      if (count($plugin) > 0) {
+        return $plugin;
+      }
+    }
+    return NULL;
   }
 
   /**
@@ -58,14 +91,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.
-   */
-  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.
+   * @return \Drupal\Component\Plugin\Context\ContextInterface[]
+   *   The required plugin contexts.
    */
-  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..b00a40bbaa 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\OverridesSectionStorage;
 
 /**
  * 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(OverridesSectionStorage::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/OverridesSectionStorage.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/OverridesSectionStorage.php
new file mode 100644
index 0000000000..6a90765a6d
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/OverridesSectionStorage.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\layout_builder_test\Plugin\SectionStorage;
+
+use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage as BaseOverridesSectionStorage;
+
+class OverridesSectionStorage extends BaseOverridesSectionStorage {
+
+  /**
+   * {@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..a085fd2dcc 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\layout_builder\Functional;
 
+use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
 use Drupal\node\Entity\Node;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\views\Entity\View;
@@ -526,4 +527,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..73297d7f17 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;
@@ -51,7 +52,7 @@ protected function setUp() {
       'id' => 'defaults',
       'class' => DefaultsSectionStorage::class,
     ]);
-    $this->plugin = new DefaultsSectionStorage([], '', $definition, $this->entityTypeManager->reveal(), $entity_type_bundle_info->reveal(), $sample_entity_generator->reveal());
+    $this->plugin = new TestDefaultsSectionStorage([], '', $definition, $this->entityTypeManager->reveal(), $entity_type_bundle_info->reveal(), $sample_entity_generator->reveal());
   }
 
   /**
@@ -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'));
@@ -424,3 +429,21 @@ public function testBuildRoutes() {
   }
 
 }
+
+class TestDefaultsSectionStorage extends DefaultsSectionStorage {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+    return parent::extractIdFromRoute($value, $definition, $name, $defaults);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSectionListFromId($id) {
+    return parent::getSectionListFromId($id);
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
index 110ec2021e..6b20c60878 100644
--- a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
@@ -56,7 +56,7 @@ protected function setUp() {
       'id' => 'overrides',
       'class' => OverridesSectionStorage::class,
     ]);
-    $this->plugin = new OverridesSectionStorage([], 'overrides', $definition, $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal());
+    $this->plugin = new TestOverridesSectionStorage([], 'overrides', $definition, $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal());
   }
 
   /**
@@ -388,3 +388,21 @@ public function testBuildRoutes() {
   }
 
 }
+
+class TestOverridesSectionStorage extends OverridesSectionStorage {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+    return parent::extractIdFromRoute($value, $definition, $name, $defaults);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSectionListFromId($id) {
+    return parent::getSectionListFromId($id);
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
index 392cd8939e..fcfb182965 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
@@ -2,6 +2,7 @@
 
 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;
@@ -58,30 +59,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 +77,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);
