diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index 6acd1e6..990b36e 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -225,6 +225,13 @@ field.widget.settings.checkbox:
       type: boolean
       label: 'Use field label instead of the "On value" as label'
 
+field.formatter.settings.string:
+  type: mapping
+  mapping:
+    entity_link:
+      type: boolean
+      label: 'Link to the entity'
+
 field.formatter.settings.number_decimal:
   type: mapping
   label: 'Number decimal display format settings'
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
index 544ae46..521a62a 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
@@ -8,8 +8,13 @@
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
 use Drupal\Component\Utility\String;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Plugin implementation of the 'string' formatter.
@@ -27,7 +32,89 @@
  *   }
  * )
  */
-class StringFormatter extends FormatterBase {
+class StringFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * Constructs a StringFormatter instance.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param array $third_party_settings
+   *   Any third party settings settings.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityManagerInterface $entity_manager) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $configuration['third_party_settings'],
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    $options = parent::defaultSettings();
+
+    $options['link_to_entity'] = FALSE;
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+
+    if ($this->fieldDefinition->getType() === 'string') {
+      $entity_type = $this->entityManager->getDefinition($this->fieldDefinition->getTargetEntityTypeId());
+      $form['link_to_entity'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Link to the @entity_label', ['@entity_label' => $entity_type->getLabel()]),
+        '#default_value' => $this->getSetting('link_to_entity'),
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $build = [];
+    if ($this->fieldDefinition->getType() === 'string' && $this->getSetting('link_to_entity')) {
+      $entity_type = $this->entityManager->getDefinition($this->fieldDefinition->getTargetEntityTypeId());
+      $build['#markup'] = $this->t('Linked to the @entity_label', ['@entity_label' => $entity_type->getLabel()]);
+    }
+    return $build;
+  }
 
   /**
    * {@inheritdoc}
@@ -35,10 +122,27 @@ class StringFormatter extends FormatterBase {
   public function viewElements(FieldItemListInterface $items) {
     $elements = array();
 
+    $url = NULL;
+    // Add support to link to the entity itself.
+    if ($this->fieldDefinition->getType() === 'string' && $this->getSetting('link_to_entity') && ($entity = $items->getEntity()) && $entity->hasLinkTemplate('canonical')) {
+      $url = $entity->urlInfo();
+    }
+
     foreach ($items as $delta => $item) {
       // The text value has no text format assigned to it, so the user input
       // should equal the output, including newlines.
-      $elements[$delta] = array('#markup' => nl2br(String::checkPlain($item->value)));
+      $string = nl2br(String::checkPlain($item->value));
+
+      if ($url) {
+        $elements[$delta] = [
+          '#type' => 'link',
+          '#title' => $string,
+          '#url' => $url,
+        ];
+      }
+      else {
+        $elements[$delta] = ['#markup' => $string];
+      }
     }
 
     return $elements;
diff --git a/core/modules/field/src/Tests/String/StringFormatterTest.php b/core/modules/field/src/Tests/String/StringFormatterTest.php
index 0cf3f77..bc23148 100644
--- a/core/modules/field/src/Tests/String/StringFormatterTest.php
+++ b/core/modules/field/src/Tests/String/StringFormatterTest.php
@@ -58,6 +58,8 @@ protected function setUp() {
 
     // Configure the theme system.
     $this->installConfig(array('system', 'field'));
+    $this->installSchema('system', 'router');
+    \Drupal::service('router.builder')->rebuild();
     $this->installEntitySchema('entity_test');
 
     $this->entityType = 'entity_test';
@@ -122,6 +124,23 @@ public function testStringFormatter() {
     // Verify the cache tags.
     $build = $entity->{$this->fieldName}->view();
     $this->assertTrue(!isset($build[0]['#cache']), format_string('The string formatter has no cache tags.'));
+
+    // Set the formatter to link to the entity.
+    $this->display->setComponent($this->fieldName, [
+      'type' => 'string',
+      'settings' => [
+        'link_to_entity' => TRUE,
+      ],
+    ]);
+    $this->display->save();
+
+    $value = $this->randomMachineName();
+    $entity->{$this->fieldName}->value = $value;
+    $entity->save();
+
+    $this->renderEntityFields($entity, $this->display);
+    $this->assertLink($value, 0);
+    $this->assertLinkByHref($entity->url());
   }
 
 }
diff --git a/core/modules/field_ui/src/Tests/EntityDisplayTest.php b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
index 82003d8..1ebd54f 100644
--- a/core/modules/field_ui/src/Tests/EntityDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
@@ -69,7 +69,9 @@ public function testEntityDisplayCRUD() {
       'label' => 'hidden',
       'type' => 'string',
       'weight' => -5,
-      'settings' => array(),
+      'settings' => array(
+        'link_to_entity' => FALSE,
+      ),
       'third_party_settings' => array(),
     );
     $this->assertEqual($display->getComponents(), $expected);
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php
index 4759dc0..56eabf5 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php
@@ -178,7 +178,7 @@ public function testEntityDisplaySettings() {
     // Test phone field.
     $expected['weight'] = 9;
     $expected['type'] = 'string';
-    $expected['settings'] = array();
+    $expected['settings'] = array('link_to_entity' => FALSE);
     $component = $display->getComponent('field_test_phone');
     $this->assertEqual($component, $expected, "node.story.teaser field_test_phone is of type telephone.");
 
diff --git a/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php
index 5fdafdf..e114ebf 100644
--- a/core/modules/simpletest/src/AssertContentTrait.php
+++ b/core/modules/simpletest/src/AssertContentTrait.php
@@ -141,6 +141,16 @@ protected function parse() {
   }
 
   /**
+   * Get the current URL from the cURL handler.
+   *
+   * @return string
+   *   The current URL.
+   */
+  protected function getUrl() {
+    return isset($this->url) ? $this->url : 'no-url';
+  }
+
+  /**
    * Builds an XPath query.
    *
    * Builds an XPath query by replacing placeholders in the query by the value
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 93a5047..f15e780 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -2308,16 +2308,6 @@ protected function getAbsoluteUrl($path) {
   }
 
   /**
-   * Get the current URL from the cURL handler.
-   *
-   * @return
-   *   The current URL.
-   */
-  protected function getUrl() {
-    return $this->url;
-  }
-
-  /**
    * Gets the HTTP response headers of the requested page.
    *
    * Normally we are only interested in the headers returned by the last
