diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml b/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
index b846939a6e076f80c7e38f90fa21ef034b5d917b..f9ca25544ab943f7e9529a1361c62aad66e3823c 100644
--- a/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
+++ b/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
@@ -145,3 +145,19 @@ ajax_test.http_methods.dialog:
     _controller: Drupal\ajax_test\Controller\AjaxTestController::httpMethodsDialog
   requirements:
     _access: 'TRUE'
+
+ajax_test.link_page.dialog:
+  path: '/ajax-test/link-page-dialog'
+  defaults:
+    _title: 'AJAX link page'
+    _controller: '\Drupal\ajax_test\Controller\AjaxTestController::linkPageDialog'
+  requirements:
+    _access: 'TRUE'
+
+ajax_test.link_page.dialog_contents:
+  path: '/ajax-test/link-page-dialog-contents'
+  defaults:
+    _title_callback: '\Drupal\ajax_test\Controller\AjaxTestController::linkPageDialogTitle'
+    _controller: '\Drupal\ajax_test\Controller\AjaxTestController::httpMethodsDialog'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
index b91b37d038e7d9b005cb3e757f133c58ce6eda75..fcedd115edb6a2660564a6ea0a7925b661c38353 100644
--- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
+++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
@@ -457,4 +457,40 @@ public function httpMethodsDialog(): array {
     return ['#markup' => 'Modal dialog contents'];
   }
 
+  /**
+   * Provides an Ajax link that open in dialog.
+   *
+   * @return array
+   *   The AJAX link.
+   */
+  public function linkPageDialog(): array {
+    return [
+      '#type' => 'link',
+      '#title' => 'Modal link',
+      '#url' => Url::fromRoute('ajax_test.link_page.dialog_contents'),
+      '#attributes' => [
+        'class' => [
+          'use-ajax',
+        ],
+        'data-dialog-type' => 'dialog',
+      ],
+      '#attached' => [
+        'library' => [
+          'core/drupal.dialog.ajax',
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Provides a title to the page.
+   *
+   * @return string
+   *   The page title.
+   */
+  public function linkPageDialogTitle(): string {
+    $title = 'Dialog link page title';
+    return $title;
+  }
+
 }
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
index 7cb0ba26eaddcc6083dec9b8433a1cf10f6f7378..bdd324020866d453050e89517767df29de6e6bb2 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
@@ -216,6 +216,13 @@ public function testDialog(): void {
 
     $form_title = $dialog_add->find('css', "span.ui-dialog-title:contains('Add contact form')");
     $this->assertNotNull($form_title, 'The add form title is as expected.');
+
+    // Test: dialog link opener with title callback.
+    $page = $this->getSession()->getPage();
+    $assert_session = $this->assertSession();
+    $this->drupalGet("/ajax-test/link-page-dialog");
+    $page->clickLink('Modal link');
+    $this->assertEquals('Dialog link page title', $assert_session->waitForElement('css', '.ui-dialog-title')->getText());
   }
 
   /**