diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index be92cd96bb99f82bf8b7c2877199024568c8b87a..f44ebc46850f4bece658165fbe81703161a1460e 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -362,6 +362,11 @@ layout_plugin.settings:
     label:
       type: label
       label: 'Label'
+    context_mapping:
+      type: sequence
+      label: 'Context assignments'
+      sequence:
+        type: string
 
 layout_plugin.settings.*:
   type: layout_plugin.settings
diff --git a/core/lib/Drupal/Core/Layout/LayoutDefault.php b/core/lib/Drupal/Core/Layout/LayoutDefault.php
index 175844fe1e33307d0b72e3813ae2bce0d2a3db51..afeedb85d27206b8d73214ba3c630486b92fcb8e 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefault.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefault.php
@@ -4,6 +4,8 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait;
+use Drupal\Core\Plugin\ContextAwarePluginTrait;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Plugin\PluginFormInterface;
 
@@ -12,6 +14,9 @@
  */
 class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInterface {
 
+  use ContextAwarePluginAssignmentTrait;
+  use ContextAwarePluginTrait;
+
   /**
    * The layout definition.
    *
@@ -95,6 +100,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#title' => $this->t('Administrative label'),
       '#default_value' => $this->configuration['label'],
     ];
+    $contexts = $form_state->getTemporaryValue('gathered_contexts') ?: [];
+    $form['context_mapping'] = $this->addContextAssignmentElement($this, $contexts);
     return $form;
   }
 
diff --git a/core/lib/Drupal/Core/Layout/LayoutDefinition.php b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
index c87b618d113f50b8d96cac0a6306f58cd9560bc1..033175188a69c7cf9ae49f8ea869d4d38a183a26 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefinition.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\Layout;
 
+use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionTrait;
 use Drupal\Component\Plugin\Definition\DerivablePluginDefinitionInterface;
 use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
 use Drupal\Component\Plugin\Definition\PluginDefinition;
@@ -11,8 +13,9 @@
 /**
  * Provides an implementation of a layout definition and its metadata.
  */
-class LayoutDefinition extends PluginDefinition implements PluginDefinitionInterface, DerivablePluginDefinitionInterface, DependentPluginDefinitionInterface {
+class LayoutDefinition extends PluginDefinition implements PluginDefinitionInterface, DerivablePluginDefinitionInterface, DependentPluginDefinitionInterface, ContextAwarePluginDefinitionInterface {
 
+  use ContextAwarePluginDefinitionTrait;
   use DependentPluginDefinitionTrait;
 
   /**
@@ -129,6 +132,16 @@ class LayoutDefinition extends PluginDefinition implements PluginDefinitionInter
    *   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_definitions'])) {
+      foreach ($definition['context_definitions'] as $name => $context_definition) {
+        $this->addContextDefinition($name, $context_definition);
+      }
+      unset($definition['context_definitions']);
+    }
+
     foreach ($definition as $property => $value) {
       $this->set($property, $value);
     }
diff --git a/core/lib/Drupal/Core/Layout/LayoutInterface.php b/core/lib/Drupal/Core/Layout/LayoutInterface.php
index 400a0d9af41f44e26a7fc87e00d28b0017de0423..33858a546d7fc0f2696c408873f4b9bf51cb9b7c 100644
--- a/core/lib/Drupal/Core/Layout/LayoutInterface.php
+++ b/core/lib/Drupal/Core/Layout/LayoutInterface.php
@@ -6,11 +6,12 @@
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Component\Plugin\ConfigurableInterface;
 use Drupal\Component\Plugin\DependentPluginInterface;
+use Drupal\Core\Plugin\ContextAwarePluginInterface;
 
 /**
  * Provides an interface for static Layout plugins.
  */
-interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface {
+interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface, ContextAwarePluginInterface {
 
   /**
    * Build a render array for layout with regions.
diff --git a/core/modules/layout_builder/layout_builder.post_update.php b/core/modules/layout_builder/layout_builder.post_update.php
index 47d94aa52cbd9c1367fbf06265d3af2b471af3d9..e40adb73429885d9ddbaf44689fcee8ba6a9fa57 100644
--- a/core/modules/layout_builder/layout_builder.post_update.php
+++ b/core/modules/layout_builder/layout_builder.post_update.php
@@ -5,6 +5,11 @@
  * Post update functions for Layout Builder.
  */
 
+use Drupal\Core\Config\Entity\ConfigEntityUpdater;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+
+use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
+
 /**
  * Implements hook_removed_post_updates().
  */
@@ -34,3 +39,31 @@ function layout_builder_removed_post_updates() {
 function layout_builder_post_update_override_entity_form_controller() {
   // Empty post-update hook.
 }
+
+/**
+ * Update view displays that use Layout Builder to add empty context mappings.
+ */
+function layout_builder_post_update_section_storage_context_mapping(&$sandbox = []) {
+  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+
+  $callback = function (EntityViewDisplayInterface $display) {
+    $needs_update = FALSE;
+
+    // Only update entity view displays where Layout Builder is enabled.
+    if ($display instanceof LayoutEntityDisplayInterface && $display->isLayoutBuilderEnabled()) {
+      foreach ($display->getSections() as $section) {
+        // Add an empty context mapping to each section where one doesn't exist.
+        $section->setLayoutSettings($section->getLayoutSettings() + [
+          'context_mapping' => [],
+        ]);
+
+        // Flag this display as needing to be updated.
+        $needs_update = TRUE;
+      }
+    }
+
+    return $needs_update;
+  };
+
+  $config_entity_updater->update($sandbox, 'entity_view_display', $callback);
+}
diff --git a/core/modules/layout_builder/src/Controller/ChooseSectionController.php b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
index 1eee96b1aa5d50a28d9dbf314131bc804ea6b786..7edcf0768c38c9665a01bbdc31d9c3163122e63a 100644
--- a/core/modules/layout_builder/src/Controller/ChooseSectionController.php
+++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
+use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
 use Drupal\layout_builder\LayoutBuilderHighlightTrait;
 use Drupal\layout_builder\SectionStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -21,6 +22,7 @@
 class ChooseSectionController implements ContainerInjectionInterface {
 
   use AjaxHelperTrait;
+  use LayoutBuilderContextTrait;
   use LayoutBuilderHighlightTrait;
   use StringTranslationTrait;
 
@@ -63,7 +65,7 @@ public static function create(ContainerInterface $container) {
    */
   public function build(SectionStorageInterface $section_storage, int $delta) {
     $items = [];
-    $definitions = $this->layoutManager->getFilteredDefinitions('layout_builder', [], ['section_storage' => $section_storage]);
+    $definitions = $this->layoutManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), ['section_storage' => $section_storage]);
     foreach ($definitions as $plugin_id => $definition) {
       $layout = $this->layoutManager->createInstance($plugin_id);
       $item = [
diff --git a/core/modules/layout_builder/src/Element/LayoutBuilder.php b/core/modules/layout_builder/src/Element/LayoutBuilder.php
index 0814604bbcf72fe79bad6720606504eb45c452ba..e218e4e1cab286a1d238e5f4daf6b99263e74052 100644
--- a/core/modules/layout_builder/src/Element/LayoutBuilder.php
+++ b/core/modules/layout_builder/src/Element/LayoutBuilder.php
@@ -233,7 +233,7 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
     $storage_id = $section_storage->getStorageId();
     $section = $section_storage->getSection($delta);
 
-    $layout = $section->getLayout();
+    $layout = $section->getLayout($this->getAvailableContexts($section_storage));
     $layout_settings = $section->getLayoutSettings();
     $section_label = !empty($layout_settings['label']) ? $layout_settings['label'] : $this->t('Section @section', ['@section' => $delta + 1]);
 
diff --git a/core/modules/layout_builder/src/Form/ConfigureSectionForm.php b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
index 313910482bdfb498de9bd909a5e6032272774e64..c690d5eccc0cd1ad5b241056a26422587d52ecd2 100644
--- a/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
+++ b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
@@ -8,9 +8,11 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Form\SubformState;
 use Drupal\Core\Layout\LayoutInterface;
+use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Core\Plugin\PluginFormFactoryInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Plugin\PluginWithFormsInterface;
+use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
 use Drupal\layout_builder\Controller\LayoutRebuildTrait;
 use Drupal\layout_builder\LayoutBuilderHighlightTrait;
 use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
@@ -27,6 +29,7 @@
 class ConfigureSectionForm extends FormBase {
 
   use AjaxFormHelperTrait;
+  use LayoutBuilderContextTrait;
   use LayoutBuilderHighlightTrait;
   use LayoutRebuildTrait;
 
@@ -119,8 +122,12 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt
     else {
       $section = new Section($plugin_id);
     }
+    // Passing available contexts to the layout plugin here could result in an
+    // exception since the layout may not have a context mapping for a required
+    // context slot on creation.
     $this->layout = $section->getLayout();
 
+    $form_state->setTemporaryValue('gathered_contexts', $this->getAvailableContexts($this->sectionStorage));
     $form['#tree'] = TRUE;
     $form['layout_settings'] = [];
     $subform_state = SubformState::createForSubform($form['layout_settings'], $form, $form_state);
@@ -167,6 +174,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $subform_state = SubformState::createForSubform($form['layout_settings'], $form, $form_state);
     $this->getPluginForm($this->layout)->submitConfigurationForm($form['layout_settings'], $subform_state);
 
+    // If this layout is context-aware, set the context mapping.
+    if ($this->layout instanceof ContextAwarePluginInterface) {
+      $this->layout->setContextMapping($subform_state->getValue('context_mapping', []));
+    }
+
     $plugin_id = $this->layout->getPluginId();
     $configuration = $this->layout->getConfiguration();
 
diff --git a/core/modules/layout_builder/src/Form/MoveBlockForm.php b/core/modules/layout_builder/src/Form/MoveBlockForm.php
index b3fd9dcbf80c78115d06d5efe66a80fd75990714..ef0568ead0279cdb14434f3e36818b5f9a82fd64 100644
--- a/core/modules/layout_builder/src/Form/MoveBlockForm.php
+++ b/core/modules/layout_builder/src/Form/MoveBlockForm.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Ajax\AjaxFormHelperTrait;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
 use Drupal\layout_builder\Controller\LayoutRebuildTrait;
 use Drupal\layout_builder\LayoutBuilderHighlightTrait;
 use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
@@ -20,6 +21,7 @@
 class MoveBlockForm extends FormBase {
 
   use AjaxFormHelperTrait;
+  use LayoutBuilderContextTrait;
   use LayoutBuilderHighlightTrait;
   use LayoutRebuildTrait;
 
@@ -119,9 +121,10 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt
     $form['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockUpdateHighlightId($uuid);
 
     $sections = $section_storage->getSections();
+    $contexts = $this->getAvailableContexts($section_storage);
     $region_options = [];
     foreach ($sections as $section_delta => $section) {
-      $layout = $section->getLayout();
+      $layout = $section->getLayout($contexts);
       $layout_definition = $layout->getPluginDefinition();
       if (!($section_label = $section->getLayoutSettings()['label'])) {
         $section_label = $this->t('Section: @delta', ['@delta' => $section_delta + 1])->render();
diff --git a/core/modules/layout_builder/src/Section.php b/core/modules/layout_builder/src/Section.php
index 41fe13c57e676d8fd9d23330005618cfb6d57766..cd27437cb2f6d38df9ad81f174d0f18fd85c1811 100644
--- a/core/modules/layout_builder/src/Section.php
+++ b/core/modules/layout_builder/src/Section.php
@@ -88,17 +88,24 @@ public function toRenderArray(array $contexts = [], $in_preview = FALSE) {
       }
     }
 
-    return $this->getLayout()->build($regions);
+    return $this->getLayout($contexts)->build($regions);
   }
 
   /**
    * Gets the layout plugin for this section.
    *
+   * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
+   *   An array of available contexts.
+   *
    * @return \Drupal\Core\Layout\LayoutInterface
    *   The layout plugin.
    */
-  public function getLayout() {
-    return $this->layoutPluginManager()->createInstance($this->getLayoutId(), $this->layoutSettings);
+  public function getLayout(array $contexts = []) {
+    $layout = $this->layoutPluginManager()->createInstance($this->getLayoutId(), $this->layoutSettings);
+    if ($contexts) {
+      $this->contextHandler()->applyContextMapping($layout, $contexts);
+    }
+    return $layout;
   }
 
   /**
@@ -422,4 +429,14 @@ public function getThirdPartyProviders() {
     return array_keys($this->thirdPartySettings);
   }
 
+  /**
+   * Wraps the context handler.
+   *
+   * @return \Drupal\Core\Plugin\Context\ContextHandlerInterface
+   *   The context handler.
+   */
+  protected function contextHandler() {
+    return \Drupal::service('context.handler');
+  }
+
 }
diff --git a/core/modules/layout_builder/tests/fixtures/update/layout-builder-context-mapping.php b/core/modules/layout_builder/tests/fixtures/update/layout-builder-context-mapping.php
new file mode 100644
index 0000000000000000000000000000000000000000..355c7ce5448cf9e6905d8c55571009eff89e8311
--- /dev/null
+++ b/core/modules/layout_builder/tests/fixtures/update/layout-builder-context-mapping.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Test context mapping update path by adding a layout without a context map.
+ */
+
+use Drupal\Core\Database\Database;
+
+$connection = Database::getConnection();
+
+// Add a layout plugin to an existing entity view display.
+$display = $connection->select('config')
+  ->fields('config', ['data'])
+  ->condition('collection', '')
+  ->condition('name', 'core.entity_view_display.node.article.teaser')
+  ->execute()
+  ->fetchField();
+$display = unserialize($display);
+$display['dependencies']['module'][] = 'layout_builder';
+$display['dependencies']['module'][] = 'layout_discovery';
+$display['third_party_settings']['layout_builder']['allow_custom'] = FALSE;
+$display['third_party_settings']['layout_builder']['enabled'] = TRUE;
+$display['third_party_settings']['layout_builder']['sections'][] = [
+  'layout_id' => 'layout_onecol',
+  'layout_settings' => ['label' => ''],
+  'components' => [],
+  'third_party_settings' => [],
+];
+$connection->update('config')
+  ->fields(['data' => serialize($display)])
+  ->condition('collection', '')
+  ->condition('name', 'core.entity_view_display.node.article.teaser')
+  ->execute();
diff --git a/core/modules/layout_builder/tests/fixtures/update/layout-builder.php b/core/modules/layout_builder/tests/fixtures/update/layout-builder.php
new file mode 100644
index 0000000000000000000000000000000000000000..90e6a36bc45a69339458379e892839f722dd0035
--- /dev/null
+++ b/core/modules/layout_builder/tests/fixtures/update/layout-builder.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Test fixture.
+ */
+
+use Drupal\Core\Database\Database;
+
+$connection = Database::getConnection();
+
+// Set the schema version.
+$connection->merge('key_value')
+  ->fields(['value' => 'i:8602;'])
+  ->condition('collection', 'system.schema')
+  ->condition('name', 'layout_builder')
+  ->execute();
+
+// Update core.extension.
+$extensions = $connection->select('config')
+  ->fields('config', ['data'])
+  ->condition('collection', '')
+  ->condition('name', 'core.extension')
+  ->execute()
+  ->fetchField();
+$extensions = unserialize($extensions);
+$extensions['module']['layout_builder'] = 0;
+$extensions['module']['layout_discovery'] = 0;
+$connection->update('config')
+  ->fields(['data' => serialize($extensions)])
+  ->condition('collection', '')
+  ->condition('name', 'core.extension')
+  ->execute();
+
+// Add all layout_builder_removed_post_updates() as existing updates.
+require_once __DIR__ . '/../../../../layout_builder/layout_builder.post_update.php';
+require_once __DIR__ . '/../../../../layout_discovery/layout_discovery.post_update.php';
+$existing_updates = $connection->select('key_value')
+  ->fields('key_value', ['value'])
+  ->condition('collection', 'post_update')
+  ->condition('name', 'existing_updates')
+  ->execute()
+  ->fetchField();
+$existing_updates = unserialize($existing_updates);
+$existing_updates = array_merge(
+  $existing_updates,
+  array_keys(layout_builder_removed_post_updates()),
+  array_keys(layout_discovery_removed_post_updates())
+);
+$connection->update('key_value')
+  ->fields(['value' => serialize($existing_updates)])
+  ->condition('collection', 'post_update')
+  ->condition('name', 'existing_updates')
+  ->execute();
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/TestContextAwareLayout.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/TestContextAwareLayout.php
new file mode 100644
index 0000000000000000000000000000000000000000..b53e954c87036899295d3701a7fe00f5b555d281
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/TestContextAwareLayout.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\layout_builder_test\Plugin\Layout;
+
+use Drupal\Core\Layout\LayoutDefault;
+
+/**
+ * @Layout(
+ *   id = "layout_builder_test_context_aware",
+ *   label = @Translation("Layout Builder Test: Context Aware"),
+ *   regions = {
+ *     "main" = {
+ *       "label" = @Translation("Main Region")
+ *     }
+ *   },
+ *   context_definitions = {
+ *     "user" = @ContextDefinition("entity:user")
+ *   }
+ * )
+ */
+class TestContextAwareLayout extends LayoutDefault {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(array $regions) {
+    $build = parent::build($regions);
+    $build['main']['#attributes']['class'][] = 'user--' . $this->getContextValue('user')->getAccountName();
+    return $build;
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index 443af8a73fb40d9129e6d0460b638836e1cea0b8..9a1dc75c6c15dd294050bfebc9f11fa3e01dd095 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -1045,6 +1045,39 @@ public function testSectionLabels() {
     $assert_session->pageTextNotContains('My Cool Section');
   }
 
+  /**
+   * Tests that layouts can be context-aware.
+   */
+  public function testContextAwareLayouts() {
+    $assert_session = $this->assertSession();
+    $page = $this->getSession()->getPage();
+
+    $account = $this->drupalCreateUser([
+      'configure any layout',
+      'administer node display',
+    ]);
+    $this->drupalLogin($account);
+
+    $this->drupalPostForm('admin/structure/types/manage/bundle_with_section_field/display/default', ['layout[enabled]' => TRUE], 'Save');
+    $page->clickLink('Manage layout');
+    $page->clickLink('Add section');
+    $page->clickLink('Layout Builder Test: Context Aware');
+    $page->pressButton('Add section');
+    // See \Drupal\layout_builder_test\Plugin\Layout\TestContextAwareLayout::build().
+    $assert_session->elementExists('css', '.user--' . $account->getAccountName());
+    $page->clickLink('Configure Section 1');
+    $page->fillField('layout_settings[label]', 'My section');
+    $page->pressButton('Update');
+    $assert_session->linkExists('Configure My section');
+    $page->clickLink('Add block');
+    $page->clickLink('Powered by Drupal');
+    $page->pressButton('Add block');
+    $page->pressButton('Save layout');
+    $this->drupalGet('node/1');
+    // See \Drupal\layout_builder_test\Plugin\Layout\TestContextAwareLayout::build().
+    $assert_session->elementExists('css', '.user--' . $account->getAccountName());
+  }
+
   /**
    * Tests that sections can provide custom attributes.
    */
diff --git a/core/modules/layout_builder/tests/src/Functional/Update/LayoutBuilderContextMappingUpdatePathTest.php b/core/modules/layout_builder/tests/src/Functional/Update/LayoutBuilderContextMappingUpdatePathTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..20f0d067d962884e94de86dc6b81a56363d6a177
--- /dev/null
+++ b/core/modules/layout_builder/tests/src/Functional/Update/LayoutBuilderContextMappingUpdatePathTest.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\Tests\layout_builder\Functional\Update;
+
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Tests the upgrade path for Layout Builder layout context mappings.
+ *
+ * @see layout_builder_post_update_section_storage_context_mapping()
+ *
+ * @group layout_builder
+ */
+class LayoutBuilderContextMappingUpdatePathTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-9.0.0.bare.standard.php.gz',
+      __DIR__ . '/../../../fixtures/update/layout-builder.php',
+      __DIR__ . '/../../../fixtures/update/layout-builder-context-mapping.php',
+    ];
+  }
+
+  /**
+   * Tests the upgrade path for Layout Builder layout context mappings.
+   */
+  public function testRunUpdates() {
+    $data = EntityViewDisplay::load('node.article.teaser')->toArray();
+    $this->assertSame(TRUE, $data['third_party_settings']['layout_builder']['enabled']);
+    $this->assertArrayNotHasKey('context_mapping', $data['third_party_settings']['layout_builder']['sections'][0]->toArray()['layout_settings']);
+
+    $this->runUpdates();
+
+    $data = EntityViewDisplay::load('node.article.teaser')->toArray();
+    $this->assertSame(TRUE, $data['third_party_settings']['layout_builder']['enabled']);
+    $this->assertSame([], $data['third_party_settings']['layout_builder']['sections'][0]->toArray()['layout_settings']['context_mapping']);
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionTest.php b/core/modules/layout_builder/tests/src/Unit/SectionTest.php
index 1d3e7a24ff940a7fdd022ff322c84b5af00b3a57..2e21947de9ddc977afe22a16cc5979783586858e 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionTest.php
@@ -2,6 +2,10 @@
 
 namespace Drupal\Tests\layout_builder\Unit;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Layout\LayoutInterface;
+use Drupal\Core\Layout\LayoutPluginManagerInterface;
+use Drupal\Core\Plugin\Context\ContextHandlerInterface;
 use Drupal\layout_builder\Section;
 use Drupal\layout_builder\SectionComponent;
 use Drupal\Tests\UnitTestCase;
@@ -362,4 +366,40 @@ public function testGetThirdPartyProviders() {
     $this->assertSame(['bad_judgement'], $this->section->getThirdPartyProviders());
   }
 
+  /**
+   * @covers ::getLayout
+   * @dataProvider providerTestGetLayout
+   */
+  public function testGetLayout(array $contexts, bool $should_context_apply) {
+    $layout = $this->prophesize(LayoutInterface::class);
+    $layout_plugin_manager = $this->prophesize(LayoutPluginManagerInterface::class);
+    $layout_plugin_manager->createInstance('layout_onecol', [])->willReturn($layout->reveal());
+
+    $context_handler = $this->prophesize(ContextHandlerInterface::class);
+    if ($should_context_apply) {
+      $context_handler->applyContextMapping($layout->reveal(), $contexts)->shouldBeCalled();
+    }
+    else {
+      $context_handler->applyContextMapping($layout->reveal(), $contexts)->shouldNotBeCalled();
+    }
+
+    $container = new ContainerBuilder();
+    $container->set('plugin.manager.core.layout', $layout_plugin_manager->reveal());
+    $container->set('context.handler', $context_handler->reveal());
+    \Drupal::setContainer($container);
+
+    $output = $this->section->getLayout($contexts);
+    $this->assertSame($layout->reveal(), $output);
+  }
+
+  /**
+   * Provides test data for ::testGetLayout().
+   */
+  public function providerTestGetLayout() {
+    $data = [];
+    $data['contexts'] = [['foo' => 'bar'], TRUE];
+    $data['no contexts'] = [[], FALSE];
+    return $data;
+  }
+
 }