diff --git a/config/schema/page_manager.schema.yml b/config/schema/page_manager.schema.yml
index 17c5902..1f1a428 100644
--- a/config/schema/page_manager.schema.yml
+++ b/config/schema/page_manager.schema.yml
@@ -38,6 +38,25 @@ page_manager.page.*:
       sequence:
         - type: condition.plugin.[id]
           label: 'Access Condition'
+    static_context:
+      type: sequence
+      label: Static context list
+      sequence:
+        - type: mapping
+          label: 'Static context'
+          mapping:
+            name:
+              type: string
+              label: 'Machine-readable name of the context'
+            label:
+              type: label
+              label: 'Label of the context'
+            type:
+              type: string
+              label: 'Context type'
+            value:
+              type: string
+              label: 'Context value'
     dependencies:
       type: config_dependencies
       label: 'Dependencies'
diff --git a/js/autocomplete-reference-update.js b/js/autocomplete-reference-update.js
new file mode 100644
index 0000000..64775b0
--- /dev/null
+++ b/js/autocomplete-reference-update.js
@@ -0,0 +1,38 @@
+/**
+ * @file
+ * Attaches entity-type selection behaviors to the static context selection form.
+ *
+ * Based on dynamic-entity-reference-widget.js from
+ * http://drupal.org/project/dynamic_entity_reference.
+ */
+
+(function ($) {
+
+  "use strict";
+
+  Drupal.behaviors.pageManagerDynamicEntityReferenceAutocomplete = {
+    attach: function (context) {
+      var $context = $(context);
+      var $selects = $context.find('select.page-manager-autocomplete-reference-update').once('page-manager-autocomplete-reference-update');
+      if ($selects.length) {
+        $selects.change(function() {
+          var $select = $(this);
+          var $autocomplete = $select.parents('.autocomplete-reference').find('.form-autocomplete');
+          var basePath;
+          if (!(basePath = $autocomplete.data('base-autocomplete-path'))) {
+            // This is the first time this has run, copy the default value.
+            basePath = $autocomplete.attr('data-autocomplete-path');
+            // By default, the base path contains the default suffix, so cut
+            // that off.
+            basePath = basePath.substring(0, basePath.lastIndexOf('/') + 1);
+            // Store for subsequent calls.
+            $autocomplete.data('base-autocomplete-path', basePath);
+          }
+          $autocomplete.attr('data-autocomplete-path', basePath + $select.val());
+        });
+        $selects.change();
+      }
+    }
+  };
+
+})(jQuery);
diff --git a/page_manager.libraries.yml b/page_manager.libraries.yml
new file mode 100644
index 0000000..ee65fb1
--- /dev/null
+++ b/page_manager.libraries.yml
@@ -0,0 +1,8 @@
+drupal.autocomplete_reference_update:
+  version: VERSION
+  js:
+    js/autocomplete-reference-update.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupal.form
diff --git a/page_manager.routing.yml b/page_manager.routing.yml
index 5bf8063..0523229 100644
--- a/page_manager.routing.yml
+++ b/page_manager.routing.yml
@@ -82,6 +82,32 @@ page_manager.access_condition_delete:
   requirements:
     _entity_access: page.update
 
+#### Static Contexts
+
+page_manager.static_context_add:
+  path: '/admin/structure/page_manager/manage/{page}/context/add'
+  defaults:
+    _form: '\Drupal\page_manager\Form\StaticContextAddForm'
+    _title: 'Add new static context'
+  requirements:
+    _entity_access: page.update
+
+page_manager.static_context_edit:
+  path: '/admin/structure/page_manager/manage/{page}/context/edit/{name}'
+  defaults:
+    _form: '\Drupal\page_manager\Form\StaticContextEditForm'
+    _title_callback: '\Drupal\page_manager\Controller\PageManagerController::editStaticContextTitle'
+  requirements:
+    _entity_access: page.update
+
+page_manager.static_context_delete:
+  path: '/admin/structure/page_manager/manage/{page}/context/delete/{name}'
+  defaults:
+    _form: '\Drupal\page_manager\Form\StaticContextDeleteForm'
+    _title: 'Delete static context'
+  requirements:
+    _entity_access: page.update
+
 #### Display variants
 
 page_manager.display_variant_select:
@@ -181,3 +207,10 @@ page_manager.selection_condition_delete:
     _title: 'Delete selection condition'
   requirements:
     _entity_access: page.update
+
+page_manager.autocomplete_entity:
+  path: '/page_manager/autocomplete/{entity_type_id}'
+  defaults:
+    _controller: '\Drupal\page_manager\Controller\AutocompleteController::autocompleteEntity'
+  requirements:
+    _permission: 'administer pages'
diff --git a/page_manager.services.yml b/page_manager.services.yml
index 62b4dad..abe22eb 100644
--- a/page_manager.services.yml
+++ b/page_manager.services.yml
@@ -9,6 +9,10 @@ services:
     arguments: ['@router.route_provider', '@request_stack']
     tags:
       - { name: 'event_subscriber' }
+  page_manager.static_context:
+    class: Drupal\page_manager\EventSubscriber\StaticContext
+    tags:
+      - { name: 'event_subscriber' }
   page_manager.page_manager_routes:
     class: Drupal\page_manager\Routing\PageManagerRoutes
     arguments: ['@entity.manager']
diff --git a/src/Context/EntityLazyLoadContext.php b/src/Context/EntityLazyLoadContext.php
new file mode 100644
index 0000000..1556319
--- /dev/null
+++ b/src/Context/EntityLazyLoadContext.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Context\EntityLazyLoadContext.
+ */
+
+namespace Drupal\page_manager\Context;
+
+use Drupal\Component\Plugin\Context\ContextDefinitionInterface;
+use Drupal\Core\Plugin\Context\Context;
+
+class EntityLazyLoadContext extends Context {
+
+  /**
+   * The entity UUID.
+   *
+   * @var string
+   */
+  protected $uuid;
+
+  /**
+   * Construct an EntityLazyLoadContext object.
+   *
+   * @param Drupal\Component\Plugin\Context\ContextDefinitionInterface $context_definition
+   *   The context definition.
+   * @param string $uuid
+   *   The UUID of the entity.
+   */
+  public function __construct(ContextDefinitionInterface $context_definition, $uuid) {
+    parent::__construct($context_definition);
+    $this->uuid = $uuid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContextValue() {
+    if (!$this->contextValue) {
+      $this->contextValue = \Drupal::entityManager()->loadEntityByUuid(substr($this->contextDefinition->getDataType(), 7), $this->uuid);
+    }
+    return $this->contextValue;
+  }
+
+
+}
diff --git a/src/Controller/AutocompleteController.php b/src/Controller/AutocompleteController.php
new file mode 100644
index 0000000..8e96eba
--- /dev/null
+++ b/src/Controller/AutocompleteController.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Controller\AutocompleteController.
+ */
+
+namespace Drupal\page_manager\Controller;
+
+use Drupal\Component\Utility\Tags;
+use Drupal\Component\Utility\Unicode;
+use Drupal\Component\Utility\String;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Entity\EntityAutocompleteMatcher;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides autocomplete route controllers for Page Manager.
+ */
+class AutocompleteController extends ControllerBase {
+
+  /**
+   * The autocomplete matcher for entity references.
+   *
+   * @var \Drupal\Core\Entity\EntityAutocompleteMatcher
+   */
+  protected $matcher;
+
+  /**
+   * Constructs an AutocompleteController object.
+   *
+   * @param \Drupal\Core\Entity\EntityAutocompleteMatcher $matcher
+   *   The autocomplete matcher for page manager.
+   */
+  public function __construct(EntityAutocompleteMatcher $matcher) {
+    $this->matcher = $matcher;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity.autocomplete_matcher')
+    );
+  }
+
+  /**
+   * Retrieves suggestions for entity autocompletion.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request.
+   * @param string $entity_type_id
+   *   The entity type ID.
+   *
+   * @return \Symfony\Component\HttpFoundation\JsonResponse
+   */
+  public function autocompleteEntity(Request $request, $entity_type_id) {
+    $matches = [];
+    // Get the typed string from the URL, if it exists.
+    if ($input = $request->query->get('q')) {
+      $typed_string = Tags::explode($input);
+      $typed_string = Unicode::strtolower(array_pop($typed_string));
+
+      $matches = $this->matcher->getMatches($entity_type_id, 'default', array(), $typed_string);
+    }
+
+    return new JsonResponse($matches);
+  }
+
+}
diff --git a/src/Controller/PageManagerController.php b/src/Controller/PageManagerController.php
index 01a52a3..1162093 100644
--- a/src/Controller/PageManagerController.php
+++ b/src/Controller/PageManagerController.php
@@ -148,6 +148,22 @@ class PageManagerController extends ControllerBase {
   }
 
   /**
+   * Route title callback.
+   *
+   * @param \Drupal\page_manager\PageInterface $page
+   *   The page entity.
+   * @param string $name
+   *   The static context name.
+   *
+   * @return string
+   *   The title for the static context edit form.
+   */
+  public function editStaticContextTitle(PageInterface $page, $name) {
+    $static_context = $page->getStaticContext($name);
+    return $this->t('Edit @label static context', ['@label' => $static_context['label']]);
+  }
+
+  /**
    * Enables or disables a Page.
    *
    * @param \Drupal\page_manager\PageInterface $page
diff --git a/src/Entity/Page.php b/src/Entity/Page.php
index c3e0ba7..50f4ff2 100644
--- a/src/Entity/Page.php
+++ b/src/Entity/Page.php
@@ -105,6 +105,15 @@ class Page extends ConfigEntityBase implements PageInterface {
   protected $use_admin_theme;
 
   /**
+   * Static context references.
+   *
+   * A list of arrays with the keys name, label, type and value.
+   *
+   * @var array
+   */
+  protected $static_context = [];
+
+  /**
    * Stores a reference to the executable version of this page.
    *
    * This is only used on runtime, and is not stored.
@@ -145,6 +154,7 @@ class Page extends ConfigEntityBase implements PageInterface {
       'access_conditions',
       'access_logic',
       'use_admin_theme',
+      'static_context',
     ];
     foreach ($names as $name) {
       $properties[$name] = $this->get($name);
@@ -278,6 +288,62 @@ class Page extends ConfigEntityBase implements PageInterface {
   /**
    * {@inheritdoc}
    */
+  public function getStaticContexts() {
+    return $this->get('static_context');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addStaticContext(array $configuration) {
+    $static_contexts = $this->getStaticContexts();
+    $static_contexts[] = $new_static;
+    $this->set('static_context', $static_contexts);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getStaticContext($name) {
+    $static_contexts = $this->getStaticContexts();
+    foreach ($static_contexts as $static_context) {
+      if ($static_context['name'] == $name) {
+        return $static_context;
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function updateStaticContext($name, $configuration) {
+    $static_contexts = $this->getStaticContexts();
+    foreach ($static_contexts as $key => $static_context) {
+      if ($static_context['name'] == $name) {
+        $static_contexts[$key] = $configuration;
+      }
+    }
+    $this->set('static_context', $static_contexts);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function removeStaticContext($name) {
+    $static_contexts = $this->getStaticContexts();
+    foreach ($static_contexts as $key => $static_context) {
+      if ($static_context['name'] == $name) {
+        unset($static_contexts[$key]);
+      }
+    }
+    $this->set('static_context', $static_contexts);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getContexts() {
     return $this->getExecutable()->getContexts();
   }
diff --git a/src/EventSubscriber/StaticContext.php b/src/EventSubscriber/StaticContext.php
new file mode 100644
index 0000000..5291816
--- /dev/null
+++ b/src/EventSubscriber/StaticContext.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\EventSubscriber\StaticContext.
+ */
+
+namespace Drupal\page_manager\EventSubscriber;
+
+use Drupal\Core\Plugin\Context\ContextDefinition;
+use Drupal\page_manager\Context\EntityLazyLoadContext;
+use Drupal\page_manager\Event\PageManagerContextEvent;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Plugin\Context\Context;
+use Drupal\Core\Session\AccountProxyInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\page_manager\Event\PageManagerEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Adds static context.
+ */
+class StaticContext implements EventSubscriberInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * Adds in the current user as a context.
+   *
+   * @param \Drupal\page_manager\Event\PageManagerContextEvent $event
+   *   The page entity context event.
+   */
+  public function onPageContext(PageManagerContextEvent $event) {
+    $executable = $event->getPageExecutable();
+    $static_contexts = $executable->getPage()->get('static_context');
+
+    foreach ($static_contexts as $static_context) {
+      $context = new EntityLazyLoadContext(new ContextDefinition($static_context['type'], $static_context['label']), $static_context['value']);
+      $executable->addContext($static_context['name'], $context);
+    }
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[PageManagerEvents::PAGE_CONTEXT][] = 'onPageContext';
+    return $events;
+  }
+
+}
diff --git a/src/Form/PageEditForm.php b/src/Form/PageEditForm.php
index 9a70a23..281f4a7 100644
--- a/src/Form/PageEditForm.php
+++ b/src/Form/PageEditForm.php
@@ -10,8 +10,12 @@ namespace Drupal\page_manager\Form;
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\Query\QueryFactory;
+use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a form for editing a page entity.
@@ -19,6 +23,36 @@ use Drupal\Core\Url;
 class PageEditForm extends PageFormBase {
 
   /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Construct a new PageEditForm.
+   *
+   * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
+   *   The entity query factory.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(QueryFactory $entity_query, EntityManagerInterface $entity_manager) {
+    $this->entityQuery = $entity_query;
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity.query'),
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
@@ -44,6 +78,77 @@ class PageEditForm extends PageFormBase {
       ]
     ]);
 
+    $form['context'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Available context'),
+      '#open' => TRUE,
+    ];
+    $form['context']['add'] = [
+      '#type' => 'link',
+      '#title' => $this->t('Add new static context'),
+      '#url' => Url::fromRoute('page_manager.static_context_add', [
+        'page' => $this->entity->id(),
+      ]),
+      '#attributes' => $add_button_attributes,
+      '#attached' => [
+        'library' => [
+          'core/drupal.ajax',
+        ],
+      ],
+    ];
+    $form['context']['available_context'] = [
+      '#type' => 'table',
+      '#header' => [
+        $this->t('Label'),
+        $this->t('Name'),
+        $this->t('Type'),
+        $this->t('Operations'),
+      ],
+      '#empty' => $this->t('There is no available context.'),
+    ];
+    $contexts = $this->entity->getContexts();
+    foreach ($contexts as $name => $context) {
+      $context_definition = $context->getContextDefinition();
+
+      $row = [];
+      $row['label'] = [
+        '#markup' => $context_definition->getLabel(),
+      ];
+      $row['name'] = [
+        '#markup' => $name,
+      ];
+      $row['type'] = [
+        '#markup' => $context_definition->getDataType(),
+      ];
+
+      // Add operation links if the context is a static context.
+      $operations = [];
+      if ($this->entity->getStaticContext($name)) {
+        $operations['edit'] = [
+          'title' => $this->t('Edit'),
+          'url' => Url::fromRoute('page_manager.static_context_edit', [
+            'page' => $this->entity->id(),
+            'name' => $name,
+          ]),
+          'attributes' => $attributes,
+        ];
+        $operations['delete'] = [
+          'title' => $this->t('Delete'),
+          'url' => Url::fromRoute('page_manager.static_context_delete', [
+            'page' => $this->entity->id(),
+            'name' => $name,
+          ]),
+          'attributes' => $attributes,
+        ];
+      }
+      $row['operations'] = [
+        '#type' => 'operations',
+        '#links' => $operations,
+      ];
+
+      $form['context']['available_context'][$name] = $row;
+    }
+
     $form['display_variant_section'] = [
       '#type' => 'details',
       '#title' => $this->t('Display variants'),
@@ -204,4 +309,52 @@ class PageEditForm extends PageFormBase {
     $form_state->setRedirect('page_manager.page_list');
   }
 
+  /**
+   * Determines if a context with that name already exists.
+   *
+   * @param string $name
+   *   The context name
+   *
+   * @return bool
+   *   TRUE if the format exists, FALSE otherwise.
+   */
+  public function contextExists($name) {
+    return isset($this->entity->getContexts()[$name]);
+  }
+
+  /**
+   * Form submit callback to add a context reference.
+   */
+  public function submitStaticContext(array $form, FormStateInterface $form_state) {
+    $input = $form_state->getValue(['static', 'selection']);
+
+    // Take "label (entity id)', match the ID from parenthesis when it's a
+    // number.
+    if (preg_match("/.+\((\d+)\)/", $input, $matches)) {
+      $match = $matches[1];
+    }
+    // Match the ID when it's a string (e.g. for config entity types).
+    elseif (preg_match("/.+\(([\w.]+)\)/", $input, $matches)) {
+      $match = $matches[1];
+    }
+
+    if (!isset($match)) {
+      return;
+    }
+
+    $entity_type = $form_state->getValue(['static', 'entity_type']);
+    $entity = $this->entityManager->getStorage($entity_type)->load($match);
+    $new_static = [
+      'name' => $form_state->getValue(['static', 'name']),
+      'label' => $form_state->getValue(['static', 'label']),
+      'type' => 'entity:' . $entity_type,
+      'value' => $entity->uuid(),
+    ];
+
+    $static_context = (array) $this->entity->get('static_context');
+    $static_context[] = $new_static;
+    $this->entity->set('static_context', $static_context);
+    $this->entity->save();
+  }
+
 }
diff --git a/src/Form/StaticContextAddForm.php b/src/Form/StaticContextAddForm.php
new file mode 100644
index 0000000..91d5177
--- /dev/null
+++ b/src/Form/StaticContextAddForm.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Form\StaticContextAddForm.
+ */
+
+namespace Drupal\page_manager\Form;
+
+use Drupal\Core\Condition\ConditionManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a form for adding a new static context.
+ */
+class StaticContextAddForm extends StaticContextFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'page_manager_static_context_add_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function submitButtonText() {
+    return $this->t('Add Static Context');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function submitMessageText() {
+    return $this->t('The %label static context has been added.', ['%label' => $this->staticContext['label']]);
+  }
+
+}
diff --git a/src/Form/StaticContextDeleteForm.php b/src/Form/StaticContextDeleteForm.php
new file mode 100644
index 0000000..b10dd04
--- /dev/null
+++ b/src/Form/StaticContextDeleteForm.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Form\StaticContextDeleteForm.
+ */
+
+namespace Drupal\page_manager\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\page_manager\PageInterface;
+use Drupal\Core\Form\ConfirmFormBase;
+
+/**
+ * Provides a form for deleting an access condition.
+ */
+class StaticContextDeleteForm extends ConfirmFormBase {
+
+  /**
+   * The page entity this selection condition belongs to.
+   *
+   * @var \Drupal\page_manager\PageInterface
+   */
+  protected $page;
+
+  /**
+   * The static context settings array.
+   *
+   * @var array
+   */
+  protected $staticContext;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'page_manager_static_context_delete_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return $this->t('Are you sure you want to delete the static context %name?', ['%name' => $this->staticContext['label']]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelUrl() {
+    return $this->page->urlInfo('edit-form');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return $this->t('Delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, PageInterface $page = NULL, $name = NULL) {
+    $this->page = $page;
+    $this->staticContext = $page->getStaticContext($name);
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $this->page->removeStaticContext($this->staticContext['name']);
+    $this->page->save();
+    drupal_set_message($this->t('The static context %name has been removed.', ['%name' => $this->staticContext['label']]));
+    $form_state->setRedirectUrl($this->getCancelUrl());
+  }
+
+}
diff --git a/src/Form/StaticContextEditForm.php b/src/Form/StaticContextEditForm.php
new file mode 100644
index 0000000..0d52ad5
--- /dev/null
+++ b/src/Form/StaticContextEditForm.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Form\StaticContextEditForm.
+ */
+
+namespace Drupal\page_manager\Form;
+
+use Drupal\Core\Condition\ConditionManager;
+use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a form for adding a new static context.
+ */
+class StaticContextEditForm extends StaticContextFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'page_manager_static_context_edit_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function submitButtonText() {
+    return $this->t('Update Static Context');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function submitMessageText() {
+    return $this->t('The %label static context has been updated.', ['%label' => $this->staticContext['label']]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $input = $form_state->getValue(['context', 'selection']);
+    $entity_type = $form_state->getValue(['context', 'entity_type']);
+    $entity = $this->getEntityFromSelection($entity_type, $input);
+
+    $old_name = $this->staticContext['name'];
+
+    $this->staticContext = [
+      'name' => $form_state->getValue(['context', 'name']),
+      'label' => $form_state->getValue(['context', 'label']),
+      'type' => 'entity:' . $entity_type,
+      'value' => $entity->uuid(),
+    ];
+
+    $this->page->updateStaticContext($old_name, $this->staticContext);
+    $this->page->save();
+
+    // Set the submission message.
+    drupal_set_message($this->submitMessageText());
+
+    $form_state->setRedirectUrl($this->page->urlInfo('edit-form'));
+  }
+
+}
diff --git a/src/Form/StaticContextFormBase.php b/src/Form/StaticContextFormBase.php
new file mode 100644
index 0000000..1773128
--- /dev/null
+++ b/src/Form/StaticContextFormBase.php
@@ -0,0 +1,209 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_manager\Form\StaticContextFormBase.
+ */
+
+namespace Drupal\page_manager\Form;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\Entity;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\page_manager\PageInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a base form for editing and adding an access condition.
+ */
+abstract class StaticContextFormBase extends FormBase {
+
+  /**
+   * The page entity this static context belongs to.
+   *
+   * @var \Drupal\page_manager\PageInterface
+   */
+  protected $page;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * The static context configuration.
+   *
+   * @var array
+   */
+  protected $staticContext;
+
+  /**
+   * Construct a new StaticContextFormBase.
+   *
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityManagerInterface $entity_manager) {
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
+   * Returns the text to use for the submit button.
+   *
+   * @return string
+   *   The submit button text.
+   */
+  abstract protected function submitButtonText();
+
+  /**
+   * Returns the text to use for the submit message.
+   *
+   * @return string
+   *   The submit message text.
+   */
+  abstract protected function submitMessageText();
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, PageInterface $page = NULL, $name = '') {
+    $this->page = $page;
+    $this->staticContext = $this->page->getStaticContext($name);
+
+    $form['context'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Add static context'),
+      '#open' => TRUE,
+      '#attached' => [
+        'library' => [
+          'page_manager/drupal.autocomplete_reference_update',
+        ],
+      ],
+      '#attributes' => [
+        'class' => ['autocomplete-reference'],
+      ],
+      '#tree' => TRUE,
+    ];
+
+    // Allow the condition to add to the form.
+    $form['context']['label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Label'),
+      '#default_value' => $this->staticContext['label'] ?: '',
+    ];
+    $form['context']['name'] = [
+      '#type' => 'machine_name',
+      '#maxlength' => 64,
+      '#required' => FALSE,
+      '#machine_name' => [
+        'exists' => [$this, 'contextExists'],
+        'source' => ['context', 'label'],
+      ],
+      '#default_value' => $this->staticContext['name'] ?: '',
+    ];
+    $form['context']['entity_type'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Entity type'),
+      '#options' => $this->entityManager->getEntityTypeLabels(TRUE),
+      '#default_value' => 'node',
+      '#attributes' => [
+        'class' => ['page-manager-autocomplete-reference-update'],
+      ],
+    ];
+
+    $form['context']['selection'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Select entity'),
+      '#autocomplete_route_name' => 'page_manager.autocomplete_entity',
+      '#autocomplete_route_parameters' => [
+        'entity_type_id' => 'node',
+      ],
+    ];
+    if (!empty($this->staticContext['type'])) {
+      list(,$entity_type) = explode(':', $this->staticContext['type']);
+      $entity = $this->entityManager->loadEntityByUuid($entity_type, $this->staticContext['value']);
+
+      $form['context']['entity_type']['#default_value'] = $entity_type;
+      $form['context']['selection']['#default_value'] = "{$entity->label()} ({$entity->id()})";
+    }
+
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->submitButtonText(),
+      '#button_type' => 'primary',
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $input = $form_state->getValue(['context', 'selection']);
+    $entity_type = $form_state->getValue(['context', 'entity_type']);
+    $entity = $this->getEntityFromSelection($entity_type, $input);
+
+    $this->staticContext = [
+      'name' => $form_state->getValue(['context', 'name']),
+      'label' => $form_state->getValue(['context', 'label']),
+      'type' => 'entity:' . $entity_type,
+      'value' => $entity->uuid(),
+    ];
+
+    $this->page->addStaticContext($this->staticContext);
+    $this->page->save();
+
+    // Set the submission message.
+    drupal_set_message($this->submitMessageText());
+
+    $form_state->setRedirectUrl($this->page->urlInfo('edit-form'));
+  }
+
+  /**
+   * Get the entity from the selection.
+   *
+   * @param string $input
+   *   The input from the selection box.
+   *
+   * @return \Drupal\Core\Entity\Entity
+   *   The entity reference in selection.
+   */
+  function getEntityFromSelection($entity_type, $input) {
+    // Take "label (entity id)', match the ID from parenthesis when it's a
+    // number.
+    if (preg_match("/.+\((\d+)\)/", $input, $matches)) {
+      $match = $matches[1];
+    }
+    // Match the ID when it's a string (e.g. for config entity types).
+    elseif (preg_match("/.+\(([\w.]+)\)/", $input, $matches)) {
+      $match = $matches[1];
+    }
+
+    if (!isset($match)) {
+      return;
+    }
+
+    return $this->entityManager->getStorage($entity_type)->load($match);
+  }
+
+}
diff --git a/src/PageInterface.php b/src/PageInterface.php
index 19d6204..6bf20fe 100644
--- a/src/PageInterface.php
+++ b/src/PageInterface.php
@@ -96,6 +96,58 @@ interface PageInterface extends EntityInterface, EntityWithPluginCollectionInter
   public function getAccessLogic();
 
   /**
+   * Returns the static context configurations for this page entity.
+   *
+   * @return array
+   *   An array of static context configurations.
+   */
+  public function getStaticContexts();
+
+  /**
+   * Adds a new static context to the page entity.
+   *
+   * @param array $configuration
+   *   An array of configuration for the new static context.
+   *
+   * @return string
+   *   The unique machine name of the static context.
+   */
+  public function addStaticContext(array $configuration);
+
+  /**
+   * Retrieves a specific static context.
+   *
+   * @param string $name
+   *   The static context unique name.
+   *
+   * @return array
+   *   The configuration array of the static context
+   */
+  public function getStaticContext($name);
+
+  /**
+   * Updates a specific static context.
+   *
+   * @param string $name
+   *   The static context unique name.
+   * @param array $configuration
+   *   A new array of configuration for the static context.
+   *
+   * @return $this
+   */
+  public function updateStaticContext($name, $configuration);
+
+  /**
+   * Removes a specific static context.
+   *
+   * @param string $name
+   *   The static context unique name.
+   *
+   * @return $this
+   */
+  public function removeStaticContext($name);
+
+  /**
    * Gets the values for all defined contexts.
    *
    * @return \Drupal\Component\Plugin\Context\ContextInterface[]
