diff --git a/config/schema/pathauto_pattern.schema.yml b/config/schema/pathauto_pattern.schema.yml
index 1cadb39..69d0189 100644
--- a/config/schema/pathauto_pattern.schema.yml
+++ b/config/schema/pathauto_pattern.schema.yml
@@ -28,7 +28,7 @@ pathauto.pattern.*:
     weight:
       type: integer
       label: 'Weight'
-    context_definitions:
+    relationships:
       type: sequence
       label: 'Context definitions'
       sequence:
diff --git a/pathauto.install b/pathauto.install
index a8ecabf..0adbc03 100644
--- a/pathauto.install
+++ b/pathauto.install
@@ -200,3 +200,21 @@ function pathauto_update_8100() {
     return implode('</br>', $messages);
   }
 }
+
+/**
+ * Update relationship storage.
+ */
+function pathauto_update_8101() {
+  foreach (\Drupal::configFactory()->listAll('pathauto.pattern.') as $pattern_config_name) {
+    $pattern_config = \Drupal::configFactory()->getEditable($pattern_config_name);
+
+    $relationships = [];
+    foreach ((array) $pattern_config->get('context_definitions') as $context_definition) {
+      $relationships[$context_definition['id']] = ['label' => $context_definition['label']];
+    }
+
+    $pattern_config->clear('context_definitions');
+    $pattern_config->set('relationships', $relationships);
+    $pattern_config->save();
+  }
+}
diff --git a/src/Entity/PathautoPattern.php b/src/Entity/PathautoPattern.php
index f7619e8..4f56a46 100644
--- a/src/Entity/PathautoPattern.php
+++ b/src/Entity/PathautoPattern.php
@@ -7,12 +7,11 @@
 
 namespace Drupal\pathauto\Entity;
 
+use Drupal\Component\Plugin\Exception\ContextException;
 use Drupal\Core\Condition\ConditionPluginCollection;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Plugin\Context\Context;
-use Drupal\Core\Plugin\Context\ContextDefinition;
-use Drupal\Core\Plugin\Context\ContextInterface;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
 use Drupal\pathauto\PathautoPatternInterface;
@@ -110,14 +109,12 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
   protected $weight = 0;
 
   /**
-   * @var \Drupal\Core\Plugin\Context\ContextInterface[]
+   * @var array[]
+   *   Keys are context tokens, and values are arrays with the following keys:
+   *   - label (string, optional): The human-readable label of this
+   *     relationship.
    */
-  protected $contexts = [];
-
-  /**
-   * @var array
-   */
-  protected $context_definitions = [];
+  protected $relationships = [];
 
   /**
    * The plugin collection that holds the selection criteria condition plugins.
@@ -140,19 +137,6 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
     }
     $this->selection_criteria = $criteria;
 
-    /** @var \Drupal\Core\Plugin\Context\ContextInterface[] $contexts */
-    $contexts = $this->getContexts();
-    foreach ($this->getAliasType()->getContexts() as $plugin_context_id => $plugin_context) {
-      unset($contexts[$plugin_context_id]);
-    }
-    $this->context_definitions = [];
-    foreach ($contexts as $context_id => $context) {
-      $this->context_definitions[] = [
-        'id' => $context_id,
-        'label' => $context->getContextDefinition()->getLabel()
-      ];
-    }
-
     // Invalidate the static caches.
     \Drupal::service('pathauto.generator')->resetCaches();
   }
@@ -160,31 +144,6 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
   /**
    * {@inheritdoc}
    */
-  public static function postLoad(EntityStorageInterface $storage, array &$entities) {
-    /** @var \Drupal\ctools\TypedDataResolver $resolver */
-    $resolver = \Drupal::service('ctools.typed_data.resolver');
-    /** @var \Drupal\pathauto\Entity\PathautoPattern $entity */
-    foreach ($entities as $entity) {
-      foreach ($entity->getContextDefinitions() as $definition) {
-        $context = $resolver->convertTokenToContext($definition['id'], $entity->getContexts());
-        $new_definition = new ContextDefinition(
-          $context->getContextDefinition()->getDataType(),
-          $definition['label'],
-          $context->getContextDefinition()->isRequired(),
-          $context->getContextDefinition()->isMultiple(),
-          $context->getContextDefinition()->getDescription(),
-          $context->getContextDefinition()->getDefaultValue()
-        );
-        $new_context = new Context($new_definition, $context->hasContextValue() ? $context->getContextValue() : NULL);
-        $entity->addContext($definition['id'], $new_context);
-      }
-    }
-    parent::postLoad($storage, $entities);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function postDelete(EntityStorageInterface $storage, array $entities) {
     parent::postDelete($storage, $entities);
     // Invalidate the static caches.
@@ -256,36 +215,36 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
   /**
    * {@inheritdoc}
    */
-  public function hasContext($token) {
-    $contexts = $this->getAliasType()->getContexts();
-    $contexts += $this->contexts;
-    return !empty($contexts[$token]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($token) {
+  public function getContexts() {
     $contexts = $this->getAliasType()->getContexts();
-    $contexts += $this->contexts;
-    return $contexts[$token];
+    foreach ($this->getRelationships() as $token => $definition) {
+      /** @var \Drupal\ctools\TypedDataResolver $resolver */
+      $resolver = \Drupal::service('ctools.typed_data.resolver');
+      $context = $resolver->convertTokenToContext($token, $contexts);
+      $context_definition = $context->getContextDefinition();
+      if (!empty($definition['label'])) {
+        $context_definition->setLabel($definition['label']);
+      }
+      $contexts[$token] = $context;
+    }
+    return $contexts;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getContexts() {
-    $contexts = $this->getAliasType()->getContexts();
-    $contexts += $this->contexts;
-    return $contexts;
+  public function hasRelationship($token) {
+    return isset($this->relationships[$token]);
   }
 
   /**
    * {@inheritdoc}
    */
-  public function addContext($token, ContextInterface $context) {
-    if (!$this->hasContext($token)) {
-      $this->contexts[$token] = $context;
+  public function addRelationship($token, $label = NULL) {
+    if (!$this->hasRelationship($token)) {
+      $this->relationships[$token] = [
+        'label' => $label,
+      ];
     }
     return $this;
   }
@@ -293,9 +252,11 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
   /**
    * {@inheritdoc}
    */
-  public function replaceContext($token, ContextInterface $context) {
-    if ($this->hasContext($token)) {
-      $this->contexts[$token] = $context;
+  public function replaceRelationship($token, $label) {
+    if ($this->hasRelationship($token)) {
+      $this->relationships[$token] = [
+        'label' => $label,
+      ];
     }
     return $this;
   }
@@ -303,18 +264,16 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
   /**
    * {@inheritdoc}
    */
-  public function removeContext($token) {
-    if (isset($this->contexts[$token])) {
-      unset($this->contexts[$token]);
-    }
+  public function removeRelationship($token) {
+    unset($this->relationships[$token]);
     return $this;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getContextDefinitions() {
-    return $this->context_definitions;
+  public function getRelationships() {
+    return $this->relationships;
   }
 
   /**
@@ -371,22 +330,19 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa
       // Set the context object on our Alias plugin before retrieving contexts.
       $this->getAliasType()->setContextValue($keys[0], $object);
       /** @var \Drupal\Core\Plugin\Context\ContextInterface[] $base_contexts */
-      $base_contexts = $this->getAliasType()->getContexts();
-      $contexts = [];
-      foreach ($base_contexts as $context_id => $base_context) {
-        $contexts[$context_id] = new Context($base_context->getContextDefinition(), $object);
-      }
-      /** @var \Drupal\ctools\TypedDataResolver $resolver */
-      $resolver = \Drupal::service('ctools.typed_data.resolver');
-      foreach ($this->getContexts() as $token => $context) {
-        $contexts[$token] = $resolver->convertTokenToContext($token, $contexts);
-      }
+      $contexts = $this->getContexts();
       /** @var \Drupal\Core\Plugin\Context\ContextHandler $context_handler */
       $context_handler = \Drupal::service('context.handler');
       $conditions = $this->getSelectionConditions();
       foreach ($conditions as $condition) {
         if ($condition instanceof ContextAwarePluginInterface) {
-          $context_handler->applyContextMapping($condition, $contexts);
+          try {
+            $context_handler->applyContextMapping($condition, $contexts);
+          }
+          catch (ContextException $e) {
+            watchdog_exception('pathauto', $e);
+            return FALSE;
+          }
         }
         $result = $condition->execute();
         if ($this->getSelectionLogic() == 'and' && !$result) {
diff --git a/src/Form/PatternEditForm.php b/src/Form/PatternEditForm.php
index 02615fa..4febcf6 100644
--- a/src/Form/PatternEditForm.php
+++ b/src/Form/PatternEditForm.php
@@ -244,9 +244,7 @@ class PatternEditForm extends EntityForm {
             ]
           ]
         );
-        $new_definition = new ContextDefinition('language', 'Language');
-        $new_context = new Context($new_definition);
-        $entity->addContext($language_mapping, $new_context);
+        $entity->addRelationship($language_mapping, t('Language'));
       }
 
     }
diff --git a/src/PathautoPatternInterface.php b/src/PathautoPatternInterface.php
index 33d67d2..ed0c7d4 100644
--- a/src/PathautoPatternInterface.php
+++ b/src/PathautoPatternInterface.php
@@ -8,7 +8,6 @@
 namespace Drupal\pathauto;
 
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Plugin\Context\ContextInterface;
 
 /**
  * Provides an interface for defining Pathauto pattern entities.
@@ -61,44 +60,72 @@ interface PathautoPatternInterface extends ConfigEntityInterface {
   public function setWeight($weight);
 
   /**
-   * @return bool
-   */
-  public function hasContext($token);
-
-  /**
-   * @return \Drupal\Core\Plugin\Context\ContextInterface
+   * Returns the contexts of this pattern.
+   *
+   * @return \Drupal\Core\Plugin\Context\ContextInterface[]
    */
-  public function getContext($token);
+  public function getContexts();
 
   /**
-   * @return \Drupal\Core\Plugin\Context\ContextInterface[]
+   * Returns whether a relationship exists.
+   *
+   * @param string $token
+   *   Relationship identifier.
+   *
+   * @return bool
+   *   TRUE if the relationship exists, FALSE otherwise.
    */
-  public function getContexts();
+  public function hasRelationship($token);
 
   /**
+   * Adds a relationship.
+   *
+   * The relationship will not be changed if it already exists.
+   *
    * @param string $token
-   * @param \Drupal\Core\Plugin\Context\ContextInterface $context
+   *   Relationship identifier.
+   * @param string|null $label
+   *   (optional) A label, will use the label of the referenced context if not
+   *   provided.
    *
    * @return $this
    */
-  public function addContext($token, ContextInterface $context);
+  public function addRelationship($token, $label = NULL);
 
   /**
+   * Replaces a relationship.
+   *
+   * Only already existing relationships are updated.
+   *
    * @param string $token
-   * @param \Drupal\Core\Plugin\Context\ContextInterface $context
+   *   Relationship identifier.
+   * @param string|null $label
+   *   (optional) A label, will use the label of the referenced context if not
+   *   provided.
    *
    * @return $this
    */
-  public function replaceContext($token, ContextInterface $context);
+  public function replaceRelationship($token, $label);
 
   /**
+   * Removes a relationship.
+   *
    * @param string $token
+   *   Relationship identifier.
    *
    * @return $this
    */
-  public function removeContext($token);
+  public function removeRelationship($token);
 
-  public function getContextDefinitions();
+  /**
+   * Returns a list of relationships.
+   *
+   * @return array[]
+   *   Keys are context tokens, and values are arrays with the following keys:
+   *   - label (string, optional): The human-readable label of this
+   *     relationship.
+   */
+  public function getRelationships();
 
   /**
    * Gets the selection condition collection.
diff --git a/src/Tests/PathautoUnitTest.php b/src/Tests/PathautoUnitTest.php
index 1a89d5e..f07835c 100644
--- a/src/Tests/PathautoUnitTest.php
+++ b/src/Tests/PathautoUnitTest.php
@@ -103,9 +103,7 @@ class PathautoUnitTest extends KernelTestBase {
       ]
     );
 
-    $new_definition = new ContextDefinition('language', 'Language');
-    $new_context = new Context($new_definition);
-    $pattern->addContext('node:langcode:language', $new_context);
+    $pattern->addRelationship('node:langcode:language');
     $pattern->save();
 
     $pattern = $this->createPattern('node', '/[node:title]', -1);
