diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
index 489ef4af9c..ff4dff5e51 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
@@ -98,7 +98,7 @@ public function testFieldInstanceMigration() {
     // Test a link field.
     $field = FieldConfig::load('node.story.field_test_link');
     $this->assertSame('Link Field', $field->label());
-    $expected = ['title' => 2, 'link_type' => LinkItemInterface::LINK_GENERIC];
+    $expected = ['title' => 2, 'link_type' => LinkItemInterface::LINK_GENERIC, 'handler' => 'default', 'handler_settings' => []];
     $this->assertSame($expected, $field->getSettings());
     $this->assertSame('default link title', $entity->field_test_link->title, 'Field field_test_link default title is correct.');
     $this->assertSame('https://www.drupal.org', $entity->field_test_link->uri);
diff --git a/core/modules/link/link.module b/core/modules/link/link.module
index 590c01cc91..5d50078cc0 100644
--- a/core/modules/link/link.module
+++ b/core/modules/link/link.module
@@ -5,6 +5,7 @@
  * Defines simple link field types.
  */
 
+use Drupal\Core\Field\FieldConfigInterface;
 use Drupal\Core\Link;
 use Drupal\Core\Url;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -72,3 +73,22 @@ function template_preprocess_link_formatter_link_separate(&$variables) {
 function link_preprocess_form_element__new_storage_type(&$variables) {
   $variables['#attached']['library'][] = 'link/drupal.link-icon';
 }
+
+
+/**
+ * Implements hook_ENTITY_TYPE_presave() for field_config entities.
+ *
+ * Provides a BC layer for modules providing old configurations.
+ *
+ * @todo Remove this hook in Drupal 11.0.x https://www.drupal.org/project/drupal/issues/3373258
+ */
+function link_field_config_presave(FieldConfigInterface $field) {
+  if ($field->getType() !== 'link') {
+    return;
+  }
+  if (empty($field->getSetting('handler'))) {
+    @trigger_error(sprintf('The handler setting for %s field config is missing it. This BC layer will be removed before 11.0.0.', $field->getLabel()), E_USER_DEPRECATED);
+    $field->setSetting('handler', 'default');
+    $field->setSetting('handler_settings', []);
+  }
+}
diff --git a/core/modules/link/link.post_update.php b/core/modules/link/link.post_update.php
new file mode 100644
index 0000000000..1979d1d7de
--- /dev/null
+++ b/core/modules/link/link.post_update.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains post update hooks for link module.
+ */
+
+use Drupal\Core\Config\Entity\ConfigEntityUpdater;
+use Drupal\Core\Field\FieldConfigInterface;
+
+/**
+ * Populate new 'handler' settings for the link widget.
+ */
+function link_post_update_widget_handler_settings(&$sandbox = NULL) {
+  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+  $callback = function (FieldConfigInterface $field) {
+    if ($field->getType() == 'link') {
+      return TRUE;
+    }
+
+    return FALSE;
+  };
+
+  $config_entity_updater->update($sandbox, 'field_config', $callback);
+}
diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index 2579dcbf9e..cb79d28f47 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -2,11 +2,14 @@
 
 namespace Drupal\link\Plugin\Field\FieldType;
 
+use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\Random;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\MapDataDefinition;
 use Drupal\Core\Url;
@@ -34,6 +37,8 @@ public static function defaultFieldSettings() {
     return [
       'title' => DRUPAL_OPTIONAL,
       'link_type' => LinkItemInterface::LINK_GENERIC,
+      'handler' => 'default',
+      'handler_settings' => [],
     ] + parent::defaultFieldSettings();
   }
 
@@ -86,9 +91,33 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
    * {@inheritdoc}
    */
   public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
-    $element = [];
+    $field = $form_state->getFormObject()->getEntity();
 
-    $element['link_type'] = [
+    // Get all selection plugins for this entity type. For now link supports
+    // only node entities.
+    $selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups('node');
+    $handlers_options = [];
+    foreach (array_keys($selection_plugins) as $selection_group_id) {
+      // We only display base plugins (e.g. 'default', 'views', ...) and not
+      // entity type specific plugins (e.g. 'default:node', 'default:user',
+      // ...).
+      if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
+        $handlers_options[$selection_group_id] = Html::escape($selection_plugins[$selection_group_id][$selection_group_id]['label']);
+      }
+      elseif (array_key_exists($selection_group_id . ':node', $selection_plugins[$selection_group_id])) {
+        $selection_group_plugin = $selection_group_id . ':node';
+        $handlers_options[$selection_group_plugin] = Html::escape($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
+      }
+    }
+
+    $form = [
+      '#type' => 'container',
+      '#process' => [[static::class, 'fieldSettingsAjaxProcess']],
+      '#element_validate' => [[static::class, 'fieldSettingsFormValidate']],
+
+    ];
+
+    $form['link_type'] = [
       '#type' => 'radios',
       '#title' => $this->t('Allowed link type'),
       '#default_value' => $this->getSetting('link_type'),
@@ -99,7 +128,50 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
       ],
     ];
 
-    $element['title'] = [
+    $form['handler'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Reference type'),
+      '#open' => TRUE,
+      '#tree' => TRUE,
+      '#process' => [[static::class, 'formProcessMergeParent']],
+      '#states' => [
+        'visible' => [
+          ':input[name="settings[link_type]"]' => [
+            ['value' => static::LINK_INTERNAL],
+            ['value' => static::LINK_GENERIC],
+          ],
+        ],
+      ],
+    ];
+
+    $form['handler']['handler'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Reference method'),
+      '#options' => $handlers_options,
+      '#default_value' => $field->getSetting('handler'),
+      '#required' => TRUE,
+      '#ajax' => TRUE,
+      '#limit_validation_errors' => [],
+    ];
+    $form['handler']['handler_submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->t('Change handler'),
+      '#limit_validation_errors' => [],
+      '#attributes' => [
+        'class' => ['js-hide'],
+      ],
+      '#submit' => [[static::class, 'settingsAjaxSubmit']],
+    ];
+
+    $form['handler']['handler_settings'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['entity_reference-settings']],
+    ];
+    $field->getFieldStorageDefinition()->setSetting('target_type', 'node');
+    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
+    $form['handler']['handler_settings'] += $handler->buildConfigurationForm([], $form_state);
+
+    $form['title'] = [
       '#type' => 'radios',
       '#title' => $this->t('Allow link text'),
       '#default_value' => $this->getSetting('title'),
@@ -110,9 +182,87 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
       ],
     ];
 
+    return $form;
+  }
+
+  /**
+   * Form element validation handler; Invokes selection plugin's validation.
+   *
+   * @param array $form
+   *   The form where the settings form is being included in.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state of the (entire) configuration form.
+   */
+  public static function fieldSettingsFormValidate(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\Core\Field\FieldDefinitionInterface $field */
+    $field = $form_state->getFormObject()->getEntity();
+    $field->getFieldStorageDefinition()->setSetting('target_type', 'node');
+    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
+    $handler->validateConfigurationForm($form, $form_state);
+  }
+
+  /**
+   * Render API callback: Processes the field settings form.
+   *
+   * @see static::fieldSettingsForm()
+   */
+  public static function fieldSettingsAjaxProcess($form, FormStateInterface $form_state) {
+    static::fieldSettingsAjaxProcessElement($form, $form);
+    return $form;
+  }
+
+  /**
+   * Adds the field settings to AJAX form elements.
+   *
+   * @see static::fieldSettingsAjaxProcess()
+   */
+  public static function fieldSettingsAjaxProcessElement(&$element, $main_form) {
+    if (!empty($element['#ajax'])) {
+      $element['#ajax'] = [
+        'callback' => [static::class, 'settingsAjax'],
+        'wrapper' => $main_form['#id'],
+        'element' => $main_form['#array_parents'],
+      ];
+    }
+
+    foreach (Element::children($element) as $key) {
+      static::fieldSettingsAjaxProcessElement($element[$key], $main_form);
+    }
+  }
+
+  /**
+   * Render API callback that moves entity reference elements up a level.
+   *
+   * The elements (i.e. 'handler_settings') are moved for easier processing by
+   * the validation and submission handlers.
+   *
+   * @see _entity_reference_field_settings_process()
+   */
+  public static function formProcessMergeParent($element) {
+    $parents = $element['#parents'];
+    array_pop($parents);
+    $element['#parents'] = $parents;
     return $element;
   }
 
+  /**
+   * Ajax callback for the handler settings form.
+   *
+   * @see static::fieldSettingsForm()
+   */
+  public static function settingsAjax($form, FormStateInterface $form_state) {
+    return NestedArray::getValue($form, $form_state->getTriggeringElement()['#ajax']['element']);
+  }
+
+  /**
+   * Submit handler for the non-JS case.
+   *
+   * @see static::fieldSettingsForm()
+   */
+  public static function settingsAjaxSubmit($form, FormStateInterface $form_state) {
+    $form_state->setRebuild();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index 8bee9d9806..da6adaf5b6 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -211,6 +211,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       // The link widget is doing its own processing in
       // static::getUriAsDisplayableString().
       $element['uri']['#process_default_value'] = FALSE;
+
+      $element['uri']['#selection_handler'] = $this->getFieldSetting('handler');
+      $element['uri']['#selection_settings'] = $this->getFieldSetting('handler_settings');
     }
 
     // If the field is configured to allow only internal links, add a useful
diff --git a/core/modules/link/tests/modules/link_test_base_field/link_test_base_field.module b/core/modules/link/tests/modules/link_test_base_field/link_test_base_field.module
index 94730fa4f6..7810753851 100644
--- a/core/modules/link/tests/modules/link_test_base_field/link_test_base_field.module
+++ b/core/modules/link/tests/modules/link_test_base_field/link_test_base_field.module
@@ -25,6 +25,8 @@ function link_test_base_field_entity_base_field_info(EntityTypeInterface $entity
       ->setSettings([
         'link_type' => LinkItemInterface::LINK_GENERIC,
         'title' => DRUPAL_REQUIRED,
+        'handler' => 'default',
+        'handler_settings' => [],
       ])
       ->setDisplayOptions('form', [
         'type' => 'link_default',
diff --git a/core/modules/link/tests/src/Functional/LinkFieldTest.php b/core/modules/link/tests/src/Functional/LinkFieldTest.php
index 9f1255bce7..092520c3bf 100644
--- a/core/modules/link/tests/src/Functional/LinkFieldTest.php
+++ b/core/modules/link/tests/src/Functional/LinkFieldTest.php
@@ -100,6 +100,8 @@ protected function doTestURLValidation() {
       'settings' => [
         'title' => DRUPAL_DISABLED,
         'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ]);
     $this->field->save();
@@ -285,6 +287,8 @@ protected function doTestLinkTitle() {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ]);
     $this->field->save();
@@ -411,6 +415,8 @@ protected function doTestLinkFormatter() {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ])->save();
     /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
@@ -567,6 +573,8 @@ protected function doTestLinkSeparateFormatter() {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ])->save();
     $display_options = [
@@ -698,6 +706,8 @@ protected function doTestLinkTypeOnLinkWidget() {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => $link_type,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ])->save();
 
@@ -794,6 +804,8 @@ public function testNoLinkUri() {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => LinkItemInterface::LINK_INTERNAL,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ])->save();
 
diff --git a/core/modules/link/tests/src/Kernel/LinkItemSerializationTest.php b/core/modules/link/tests/src/Kernel/LinkItemSerializationTest.php
index f0e71a659e..9f5fc3209d 100644
--- a/core/modules/link/tests/src/Kernel/LinkItemSerializationTest.php
+++ b/core/modules/link/tests/src/Kernel/LinkItemSerializationTest.php
@@ -48,7 +48,11 @@ protected function setUp(): void {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test',
       'bundle' => 'entity_test',
-      'settings' => ['link_type' => LinkItemInterface::LINK_GENERIC],
+      'settings' => [
+        'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
+      ],
     ])->save();
   }
 
diff --git a/core/modules/link/tests/src/Kernel/LinkItemTest.php b/core/modules/link/tests/src/Kernel/LinkItemTest.php
index 945768d0fa..6988e7c6df 100644
--- a/core/modules/link/tests/src/Kernel/LinkItemTest.php
+++ b/core/modules/link/tests/src/Kernel/LinkItemTest.php
@@ -42,7 +42,11 @@ protected function setUp(): void {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test',
       'bundle' => 'entity_test',
-      'settings' => ['link_type' => LinkItemInterface::LINK_GENERIC],
+      'settings' => [
+        'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
+      ],
     ])->save();
     FieldStorageConfig::create([
       'field_name' => 'field_test_external',
@@ -53,7 +57,11 @@ protected function setUp(): void {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test_external',
       'bundle' => 'entity_test',
-      'settings' => ['link_type' => LinkItemInterface::LINK_EXTERNAL],
+      'settings' => [
+        'link_type' => LinkItemInterface::LINK_EXTERNAL,
+        'handler' => 'default',
+        'handler_settings' => [],
+      ],
     ])->save();
     FieldStorageConfig::create([
       'field_name' => 'field_test_internal',
@@ -64,7 +72,11 @@ protected function setUp(): void {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test_internal',
       'bundle' => 'entity_test',
-      'settings' => ['link_type' => LinkItemInterface::LINK_INTERNAL],
+      'settings' => [
+        'link_type' => LinkItemInterface::LINK_INTERNAL,
+        'handler' => 'default',
+        'handler_settings' => [],
+      ],
     ])->save();
   }
 
diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
index c53bd382d9..91f98ec511 100644
--- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
+++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
@@ -332,6 +332,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setSettings([
         'link_type' => LinkItemInterface::LINK_GENERIC,
         'title' => DRUPAL_DISABLED,
+        'handler' => 'default',
+        'handler_settings' => [],
       ])
       ->setDisplayOptions('form', [
         'type' => 'link_default',
diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php
index 5398c561cf..35e877ea0a 100644
--- a/core/modules/shortcut/src/Entity/Shortcut.php
+++ b/core/modules/shortcut/src/Entity/Shortcut.php
@@ -149,6 +149,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setSettings([
         'link_type' => LinkItemInterface::LINK_INTERNAL,
         'title' => DRUPAL_DISABLED,
+        'handler' => 'default',
+        'handler_settings' => [],
       ])
       ->setDisplayOptions('form', [
         'type' => 'link_default',
diff --git a/core/profiles/demo_umami/config/install/field.field.block_content.banner_block.field_content_link.yml b/core/profiles/demo_umami/config/install/field.field.block_content.banner_block.field_content_link.yml
index 0ee3a806cf..5f0775208a 100644
--- a/core/profiles/demo_umami/config/install/field.field.block_content.banner_block.field_content_link.yml
+++ b/core/profiles/demo_umami/config/install/field.field.block_content.banner_block.field_content_link.yml
@@ -19,4 +19,6 @@ default_value_callback: ''
 settings:
   title: 2
   link_type: 17
+  handler: default
+  handler_settings: {  }
 field_type: link
diff --git a/core/profiles/demo_umami/config/install/field.field.block_content.footer_promo_block.field_content_link.yml b/core/profiles/demo_umami/config/install/field.field.block_content.footer_promo_block.field_content_link.yml
index ae9ccf5495..34b0ecff7a 100644
--- a/core/profiles/demo_umami/config/install/field.field.block_content.footer_promo_block.field_content_link.yml
+++ b/core/profiles/demo_umami/config/install/field.field.block_content.footer_promo_block.field_content_link.yml
@@ -19,4 +19,6 @@ default_value_callback: ''
 settings:
   title: 2
   link_type: 17
+  handler: default
+  handler_settings: {  }
 field_type: link
diff --git a/core/tests/Drupal/FunctionalTests/Routing/RouteCachingLanguageTest.php b/core/tests/Drupal/FunctionalTests/Routing/RouteCachingLanguageTest.php
index fc81b90d27..0a3f9f30a4 100644
--- a/core/tests/Drupal/FunctionalTests/Routing/RouteCachingLanguageTest.php
+++ b/core/tests/Drupal/FunctionalTests/Routing/RouteCachingLanguageTest.php
@@ -94,6 +94,8 @@ protected function setUp(): void {
       'settings' => [
         'title' => DRUPAL_OPTIONAL,
         'link_type' => LinkItemInterface::LINK_GENERIC,
+        'handler' => 'default',
+        'handler_settings' => [],
       ],
     ]);
     $field->save();
